Esempio n. 1
0
    def latency(self):
        """
        Computes the latency from the latency range.
        """
        # If we're not online then raise an exception.
        if not self.online:
            raise NetworkError("Cannot get latency for an offline connection!")

        # Constant Connections
        if self.type == CONSTANT:
            assert isinstance(self._latency, int)
            return self._latency

        if not hasattr(self, '_latency_distribution'):
            assert isinstance(self._latency, (tuple, list))

            if self.type == VARIABLE:
                self._latency_distribution = Uniform(*self._latency)

            elif self.type == NORMAL:
                self._latency_distribution = Normal(*self._latency)

            else:
                # Something went wrong
                raise UnknownType("Unkown connection type, {!r}".format(
                    self.type))

        # Non-constant connections (Variable, Normal)
        value = self._latency_distribution.get()

        # If value is zero or negative, try again
        if value <= 1:
            return self.latency()
        return value
Esempio n. 2
0
    def latency(self):
        """
        Computes the latency from the latency range.
        """
        # If we're not online then raise an exception.
        if not self.online:
            raise NetworkError(
                "Cannot get latency for an offline connection!"
            )

        # Constant Connections
        if self.type == CONSTANT:
            assert isinstance(self._latency, int)
            return self._latency

        if not hasattr(self, '_latency_distribution'):
            assert isinstance(self._latency, (tuple, list))

            if self.type == VARIABLE:
                self._latency_distribution = Uniform(*self._latency)

            elif self.type == NORMAL:
                self._latency_distribution = Normal(*self._latency)

            else:
                # Something went wrong
                raise UnknownType(
                    "Unkown connection type, {!r}".format(self.type)
                )

        # Non-constant connections (Variable, Normal)
        value = self._latency_distribution.get()

        # If value is zero or negative, try again
        if value <= 1:
            return self.latency()
        return value
Esempio n. 3
0
class Connection(object):
    """
    Create a constant or variable unidirectional connection between a source
    and a target "connectible" object. If constant, specify latency as an int
    otherwise specify the latency as a tuple.

    Connections are necessarily unidirectional so that a single replica can
    be "taken down" in the simulation, e.g. connections are deactivated to
    prevent communication; we want to do this without preventing communication
    in the other direction.
    """

    def __init__(self, network, source, target, **kwargs):
        self.network  = network
        self.source   = source
        self.target   = target
        self.type     = kwargs.get('connection', CONSTANT)
        self.online   = kwargs.get('online', True)
        self.area     = kwargs.get('area', None)

        # Set the latency protected variable
        self._latency = kwargs.get(
            'latency', settings.simulation.default_latency
        )

    @setter
    def area(self, value):
        """
        If the area is set directly, then it is stored as such. Otherwise the
        area is computed by inspecting the locations of the source and the
        target: if they are the same then local, otherwise wide.
        """
        if value is None:
            if not self.source or not self.target:
                return None
            if self.source.location == self.target.location:
                return LOCAL_AREA
            return WIDE_AREA
        return value

    def latency(self):
        """
        Computes the latency from the latency range.
        """
        # If we're not online then raise an exception.
        if not self.online:
            raise NetworkError(
                "Cannot get latency for an offline connection!"
            )

        # Constant Connections
        if self.type == CONSTANT:
            assert isinstance(self._latency, int)
            return self._latency

        if not hasattr(self, '_latency_distribution'):
            assert isinstance(self._latency, (tuple, list))

            if self.type == VARIABLE:
                self._latency_distribution = Uniform(*self._latency)

            elif self.type == NORMAL:
                self._latency_distribution = Normal(*self._latency)

            else:
                # Something went wrong
                raise UnknownType(
                    "Unkown connection type, {!r}".format(self.type)
                )

        # Non-constant connections (Variable, Normal)
        value = self._latency_distribution.get()

        # If value is zero or negative, try again
        if value <= 1:
            return self.latency()
        return value

    def up(self):
        """
        Make the connection online.
        """
        self.online = True

    def down(self):
        """
        Take the connection offline (cannot send messages)
        """
        self.online = False

    def get_latency_range(self):
        """
        Returns the latency range no matter the type.
        """
        if self.type == CONSTANT:
            return (self._latency, self._latency)
        return self._latency

    def get_latency_mean(self):
        """
        Returns the mean latency based on the connection type.
        """
        if self.type == CONSTANT:
            return self.latency
        else:
            # Make sure there is a latency distribution
            _ = self.latency()
            return self._latency_distribution.get_mean()

    def get_latency_stddev(self):
        """
        Returns the standard deviation of the latency based on connection type.
        """
        if self.type == CONSTANT:
            return 0.0
        else:
            # Make sure there is a latency distribution
            _ = self.latency()
            return self._latency_distribution.get_stddev()

    def serialize(self):
        return {
            "connection": self.type,
            "online": self.online,
            "latency": self._latency,
        }

    def __str__(self):
        """
        Returns a representation of the connection object.
        """
        arrow = {
            CONSTANT: "→",
            VARIABLE: "⇝",
            NORMAL: "⇴",
        }[self.type]

        return "{} {} {}".format(self.source, arrow, self.target)
Esempio n. 4
0
class Connection(object):
    """
    Create a constant or variable unidirectional connection between a source
    and a target "connectible" object. If constant, specify latency as an int
    otherwise specify the latency as a tuple.

    Connections are necessarily unidirectional so that a single replica can
    be "taken down" in the simulation, e.g. connections are deactivated to
    prevent communication; we want to do this without preventing communication
    in the other direction.
    """
    def __init__(self, network, source, target, **kwargs):
        self.network = network
        self.source = source
        self.target = target
        self.type = kwargs.get('connection', CONSTANT)
        self.online = kwargs.get('online', True)
        self.area = kwargs.get('area', None)

        # Set the latency protected variable
        self._latency = kwargs.get('latency',
                                   settings.simulation.default_latency)

    @setter
    def area(self, value):
        """
        If the area is set directly, then it is stored as such. Otherwise the
        area is computed by inspecting the locations of the source and the
        target: if they are the same then local, otherwise wide.
        """
        if value is None:
            if not self.source or not self.target:
                return None
            if self.source.location == self.target.location:
                return LOCAL_AREA
            return WIDE_AREA
        return value

    def latency(self):
        """
        Computes the latency from the latency range.
        """
        # If we're not online then raise an exception.
        if not self.online:
            raise NetworkError("Cannot get latency for an offline connection!")

        # Constant Connections
        if self.type == CONSTANT:
            assert isinstance(self._latency, int)
            return self._latency

        if not hasattr(self, '_latency_distribution'):
            assert isinstance(self._latency, (tuple, list))

            if self.type == VARIABLE:
                self._latency_distribution = Uniform(*self._latency)

            elif self.type == NORMAL:
                self._latency_distribution = Normal(*self._latency)

            else:
                # Something went wrong
                raise UnknownType("Unkown connection type, {!r}".format(
                    self.type))

        # Non-constant connections (Variable, Normal)
        value = self._latency_distribution.get()

        # If value is zero or negative, try again
        if value <= 1:
            return self.latency()
        return value

    def up(self):
        """
        Make the connection online.
        """
        self.online = True

    def down(self):
        """
        Take the connection offline (cannot send messages)
        """
        self.online = False

    def get_latency_range(self):
        """
        Returns the latency range no matter the type.
        """
        if self.type == CONSTANT:
            return (self._latency, self._latency)
        return self._latency

    def get_latency_mean(self):
        """
        Returns the mean latency based on the connection type.
        """
        if self.type == CONSTANT:
            return self.latency
        else:
            # Make sure there is a latency distribution
            _ = self.latency()
            return self._latency_distribution.get_mean()

    def get_latency_stddev(self):
        """
        Returns the standard deviation of the latency based on connection type.
        """
        if self.type == CONSTANT:
            return 0.0
        else:
            # Make sure there is a latency distribution
            _ = self.latency()
            return self._latency_distribution.get_stddev()

    def serialize(self):
        return {
            "connection": self.type,
            "online": self.online,
            "latency": self._latency,
        }

    def __str__(self):
        """
        Returns a representation of the connection object.
        """
        arrow = {
            CONSTANT: "→",
            VARIABLE: "⇝",
            NORMAL: "⇴",
        }[self.type]

        return "{} {} {}".format(self.source, arrow, self.target)