Esempio n. 1
0
    def access(self):
        """
        Sets up a SimPy event to wait for the access to complete or drop.
        Note that accesses are only writes - as though this were a sensor just
        streaming write accesses to the file system!
        """
        # Make sure that there is a device to write to!
        if not self.device:
            raise WorkloadException(
                "No device specified to trigger the access on!")

        # Make sure that there is a current object to write!
        if not self.current:
            raise WorkloadException(
                "No object specified as currently open on the workload!")

        # Log the results on the timeseries for the access.
        self.sim.results.update(
            WRITE, (self.device.id, self.location, self.current, self.env.now))

        # Create the event to wait for the access to complete
        self._event = self.env.event()
        self._event.callbacks.append(self.on_event_complete)

        # Create the access and register the event callbacks
        if self._access is None:
            self._access = Write(self.current, self.device)
            self._access.register_callback(COMPLETED, self.on_access_complete)
            self._access.register_callback(DROPPED, self.on_access_drop)

        # Write the access to the local device
        self.device.write(self._access)

        # Return the event to register it with the simulation process
        return self._event
Esempio n. 2
0
    def gossip(self):
        """
        Randomly select a neighbor and exchange information about the state
        of the latest entries in the log since the last anti-entropy delay.
        """

        # Gossip to one node at each location
        for location in self.locations:
            # Don't gossip to nodes in self!
            if location == self.location: continue

            # Select a random target to gossip to
            target = random.choice(list(self.remotes(location)))

            # Log the gossip that's happening
            self.sim.logger.debug("{} gossiping {} entries to {}".format(
                self, len(self.ae_cache), target))

            entries = tuple([
                Write(version.name, self, version) for version in self.ae_cache
            ])

            # Send all the values in the cache.
            self.send(target, Gossip(entries, len(self.ae_cache), -1))

        # Empty the cache on gossip
        self.ae_cache = []

        # Reset the anti-entropy timer
        self.ae_timer = Timer(self.env, self.ae_delay, self.gossip)
        self.ae_timer.start()
Esempio n. 3
0
 def access(self):
     """
     Can reconstruct an access given the information in the version, or
     the API allows the use of the setter to assign the Write access that
     created the version for storage and future use.
     """
     if not hasattr(self, '_access'):
         self._access = Write(self.name,
                              self.writer,
                              version=self,
                              started=self.created,
                              finished=self.updated)
     return self._access
Esempio n. 4
0
    def write(self, name, **kwargs):
        """
        Exposes the write API for every replica server and is the second of
        the two  primary methods of replica interaction.

        the write method exepcts the name of the object to write to and
        creates a Write event with meta informationa bout the write. It is
        the responsibility of sublcasses to perform the actual write on their
        local stores with replication.

        Note that name can also be a Write event and this method is in very
        different than the old write method (see details in read).

        This method will be adapted in the future to deal with write sizes,
        blocks, and other write meta information.
        """
        if not name:
            raise AccessError(
                "Must supply a name to write to the replica server")

        return Write.create(name, self, **kwargs)
Esempio n. 5
0
    def write(self, name, **kwargs):
        """
        Exposes the write API for every replica server and is the second of
        the two  primary methods of replica interaction.

        the write method exepcts the name of the object to write to and
        creates a Write event with meta informationa bout the write. It is
        the responsibility of sublcasses to perform the actual write on their
        local stores with replication.

        Note that name can also be a Write event and this method is in very
        different than the old write method (see details in read).

        This method will be adapted in the future to deal with write sizes,
        blocks, and other write meta information.
        """
        if not name:
            raise AccessError(
                "Must supply a name to write to the replica server"
            )

        return Write.create(name, self, **kwargs)
Esempio n. 6
0
    def access(self):
        """
        Sets up a SimPy event to wait for the access to complete or drop.
        Note that accesses are only writes - as though this were a sensor just
        streaming write accesses to the file system!
        """
        # Make sure that there is a device to write to!
        if not self.device:
            raise WorkloadException(
                "No device specified to trigger the access on!"
            )

        # Make sure that there is a current object to write!
        if not self.current:
            raise WorkloadException(
                "No object specified as currently open on the workload!"
            )

        # Log the results on the timeseries for the access.
        self.sim.results.update(
            WRITE, (self.device.id, self.location, self.current, self.env.now)
        )

        # Create the event to wait for the access to complete
        self._event  = self.env.event()
        self._event.callbacks.append(self.on_event_complete)

        # Create the access and register the event callbacks
        if self._access is None:
            self._access = Write(self.current, self.device)
            self._access.register_callback(COMPLETED, self.on_access_complete)
            self._access.register_callback(DROPPED, self.on_access_drop)

        # Write the access to the local device
        self.device.write(self._access)

        # Return the event to register it with the simulation process
        return self._event
Esempio n. 7
0
class StreamingWorkload(Workload):
    """
    A streaming workload issues accesses one after the other as soon as the
    previous access is dropped or completed (with some minimal delay between
    accesses that can be specified by overriding the `wait` method).
    """
    def __init__(self, sim, **kwargs):

        # Get the delay in milliseconds if specified
        self.delay = kwargs.pop("delay", 10)

        # Internal parameters
        self._event = None
        self._access = None

        # Initialize the workload
        super(StreamingWorkload, self).__init__(sim, **kwargs)

    def on_access_drop(self, access):
        # Retry the access after a delay
        self._access = access.clone(self.device)
        self._event.succeed()

    def on_access_complete(self, access):
        # Set the access to None to generate a new write
        self._access = None
        self._event.succeed()

    def on_event_complete(self, event):
        # Wait for a bit and execute the next access!
        self.env.process(self.wait())

    def wait(self):
        """
        Wait a fixed delay and then cause the access to occur!
        """
        yield self.env.timeout(self.delay)
        yield self.access()

    def access(self):
        """
        Sets up a SimPy event to wait for the access to complete or drop.
        Note that accesses are only writes - as though this were a sensor just
        streaming write accesses to the file system!
        """
        # Make sure that there is a device to write to!
        if not self.device:
            raise WorkloadException(
                "No device specified to trigger the access on!")

        # Make sure that there is a current object to write!
        if not self.current:
            raise WorkloadException(
                "No object specified as currently open on the workload!")

        # Log the results on the timeseries for the access.
        self.sim.results.update(
            WRITE, (self.device.id, self.location, self.current, self.env.now))

        # Create the event to wait for the access to complete
        self._event = self.env.event()
        self._event.callbacks.append(self.on_event_complete)

        # Create the access and register the event callbacks
        if self._access is None:
            self._access = Write(self.current, self.device)
            self._access.register_callback(COMPLETED, self.on_access_complete)
            self._access.register_callback(DROPPED, self.on_access_drop)

        # Write the access to the local device
        self.device.write(self._access)

        # Return the event to register it with the simulation process
        return self._event

    def run(self):
        """
        Sets off the first event that starts streaming access events.
        """
        return self.wait()
Esempio n. 8
0
class StreamingWorkload(Workload):
    """
    A streaming workload issues accesses one after the other as soon as the
    previous access is dropped or completed (with some minimal delay between
    accesses that can be specified by overriding the `wait` method).
    """

    def __init__(self, sim, **kwargs):

        # Get the delay in milliseconds if specified
        self.delay  = kwargs.pop("delay", 10)

        # Internal parameters
        self._event  = None
        self._access = None

        # Initialize the workload
        super(StreamingWorkload, self).__init__(sim, **kwargs)

    def on_access_drop(self, access):
        # Retry the access after a delay
        self._access = access.clone(self.device)
        self._event.succeed()

    def on_access_complete(self, access):
        # Set the access to None to generate a new write
        self._access = None
        self._event.succeed()

    def on_event_complete(self, event):
        # Wait for a bit and execute the next access!
        self.env.process(self.wait())

    def wait(self):
        """
        Wait a fixed delay and then cause the access to occur!
        """
        yield self.env.timeout(self.delay)
        yield self.access()

    def access(self):
        """
        Sets up a SimPy event to wait for the access to complete or drop.
        Note that accesses are only writes - as though this were a sensor just
        streaming write accesses to the file system!
        """
        # Make sure that there is a device to write to!
        if not self.device:
            raise WorkloadException(
                "No device specified to trigger the access on!"
            )

        # Make sure that there is a current object to write!
        if not self.current:
            raise WorkloadException(
                "No object specified as currently open on the workload!"
            )

        # Log the results on the timeseries for the access.
        self.sim.results.update(
            WRITE, (self.device.id, self.location, self.current, self.env.now)
        )

        # Create the event to wait for the access to complete
        self._event  = self.env.event()
        self._event.callbacks.append(self.on_event_complete)

        # Create the access and register the event callbacks
        if self._access is None:
            self._access = Write(self.current, self.device)
            self._access.register_callback(COMPLETED, self.on_access_complete)
            self._access.register_callback(DROPPED, self.on_access_drop)

        # Write the access to the local device
        self.device.write(self._access)

        # Return the event to register it with the simulation process
        return self._event

    def run(self):
        """
        Sets off the first event that starts streaming access events.
        """
        return self.wait()