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 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()
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