def plc_init(self): # Init self and container annName = 'cc_announce' self.ann_name = self.get_scoped_name('system', annName) self.start_time = pu.currenttime_ms() self.containers = {} self.contalive = {} self.last_identify = 0 # Declare CC announcement name messaging = {'name_type':'fanout', 'args':{'scope':'system'}} yield Container.configure_messaging(self.ann_name, messaging) logging.info("Declared CC anounce name: "+str(self.ann_name)) # Attach to CC announcement name annReceiver = Receiver(annName+'.'+self.receiver.label, self.ann_name) annReceiver.group = self.receiver.group self.ann_receiver = annReceiver self.ann_receiver.handle(self.receive) self.add_receiver(self.ann_receiver) annid = yield spawn(self.ann_receiver) logging.info("Listening to CC anouncements: "+str(annid)) # Start with an identify request. Will lead to an announce by myself #@TODO - Can not send a message to a base process which is not initialized! yield self.send(self.ann_name, 'identify', 'started', {'quiet':True}) # Convenience HACK: Add a few functions to container shell self._augment_shell()
def _work(self,content): myid = self.proc_name + ":" + self.receiver.spawned.id.local workid = str(content['work-id']) waittime = float(content['work']) logging.info("worker="+myid+" job="+workid+" work="+str(waittime)) yield pu.asleep(waittime) logging.info("worker="+myid+" job="+workid+" done at="+str(pu.currenttime_ms()))
def plc_init(self): # Init self and container annName = 'cc_announce' self.ann_name = self.get_scoped_name('system', annName) self.start_time = pu.currenttime_ms() self.containers = {} self.contalive = {} self.last_identify = 0 # Declare CC announcement name messaging = {'name_type': 'fanout', 'args': {'scope': 'system'}} yield Container.configure_messaging(self.ann_name, messaging) logging.info("Declared CC anounce name: " + str(self.ann_name)) # Attach to CC announcement name annReceiver = Receiver(annName + '.' + self.receiver.label, self.ann_name) annReceiver.group = self.receiver.group self.ann_receiver = annReceiver self.ann_receiver.handle(self.receive) self.add_receiver(self.ann_receiver) annid = yield spawn(self.ann_receiver) logging.info("Listening to CC anouncements: " + str(annid)) # Start with an identify request. Will lead to an announce by myself #@TODO - Can not send a message to a base process which is not initialized! yield self.send(self.ann_name, 'identify', 'started', {'quiet': True}) # Convenience HACK: Add a few functions to container shell self._augment_shell()
def _work(self, content): myid = self.proc_name + ":" + self.receiver.spawned.id.local workid = str(content['work-id']) waittime = float(content['work']) logging.info("worker=" + myid + " job=" + workid + " work=" + str(waittime)) yield pu.asleep(waittime) logging.info("worker=" + myid + " job=" + workid + " done at=" + str(pu.currenttime_ms()))
def op_result(self, content, headers, msg): ts = pu.currenttime_ms() logging.info("Work result received " + str(content) + " at " + str(ts)) workid = content['work-id'] worker = headers['sender'] self.workresult[workid] = ts if worker in self.worker: wcnt = self.worker[worker] + 1 else: wcnt = 1 self.worker[worker] = wcnt
def op_result(self, content, headers, msg): ts = pu.currenttime_ms() logging.info("Work result received "+str(content)+" at "+str(ts)) workid = content['work-id'] worker = headers['sender'] self.workresult[workid] = ts if worker in self.worker: wcnt = self.worker[worker] + 1 else: wcnt = 1 self.worker[worker] = wcnt
def op_identify(self, content, headers, msg): """ Service operation: ask for identification; respond with announcement """ logging.info("op_identify(). Sending announcement") self._check_alive() # Set the new reference. All alive containers will respond afterwards self.last_identify = int(pu.currenttime_ms()) reactor.callLater(3, self._check_alive) yield self._send_announcement('identify')
def put(self, key, value, parents=None, **kwargs): """ Puts a structured object (called entity) into the object store. Equivalent to a git-commit, with a given working tree. Distringuishes different types of values. @param key the identity of a structured object (mutable entity) @param value a value, which can be a DataObject instance or a ValueObject instance or an arbitrary value @param kwargs arbitrary keyword arguments for commit attributes @retvalue ValueRef of a commit value """ roottreeref = None if isinstance(value, DataObject): # Got DataObject. Treat it as value, make tree vref = yield self.vs.put_value(value.encode()) roottreeref = yield self.vs.put_tree(vref) elif isinstance(value, CommitValue): # Got CommitValue. Take the root tree for new commit roottreeref = value.value['roottree'] elif isinstance(value, TreeValue): # Got TreeValue. Take as root tree for new commit roottreeref = value elif isinstance(value, ValueObject): # Got ValueObject. Make tree with value roottreeref = yield self.vs.put_tree(value) else: # Got any other value. Make it a value, create a tree # Note: of this is an iterator, multiple values will be created roottreeref = yield self.vs.put_tree(value) key = _reftostr(key) # Look into repo and get most recent entity commit. If no parent was # specified, set as parent (note some concurrent process might do the same) # @todo: is this the intended behavior? what if a client does not care? cref = yield self.get_entity(key) if cref: logging.info("Previous commit exists: "+str(cref)) if parents == None: # No parents were specified but previous exists: set as parent parents = [cref] # Create commit and put in store cref = yield self.vs.put_commit(roottreeref, parents, ts=pu.currenttime_ms(), **kwargs) # Update HEAD ref for entity to new commit yield self.put_entity(key, cref) logging.debug("ObjStore put commit=%s, #entities=%s, #values=%s" % (cref.identity, self._num_entities(), self._num_values())) #logging.debug("ObjStore state: EI="+str(self.entityidx.kvs)+", OS="+str(self.objstore.kvs)) # Return the new commit as ValueRef defer.returnValue(cref)
def _send_announcement(self, event): """ Send announce message to CC broadcast name """ cdesc = {'node':str(os.uname()[1]), 'container-id':str(Container.id), 'agent':str(self.receiver.spawned.id.full), 'version':ionconst.VERSION, 'magnet':magnet.__version__, 'start-time':self.start_time, 'current-time':pu.currenttime_ms(), 'event':event} yield self.send(self.ann_name, 'announce', cdesc)
def op_announce(self, content, headers, msg): """ Service operation: announce a capability container """ logging.info("op_announce(): Received CC announcement: " + repr(content)) contid = content['container-id'] event = content['event'] if event == 'started' or event == 'identify': self.containers[contid] = content self.contalive[contid] = int(pu.currenttime_ms()) elif event == 'terminate': del self.containers[contid] del self.contalive[contid] logging.info("op_announce(): Know about %s containers!" % (len(self.containers)))
def _send_announcement(self, event): """ Send announce message to CC broadcast name """ cdesc = { 'node': str(os.uname()[1]), 'container-id': str(Container.id), 'agent': str(self.receiver.spawned.id.full), 'version': ionconst.VERSION, 'magnet': magnet.__version__, 'start-time': self.start_time, 'current-time': pu.currenttime_ms(), 'event': event } yield self.send(self.ann_name, 'announce', cdesc)
def __init__(self, receiver=None, spawnArgs=None): """ Initialize process using an optional receiver and optional spawn args @param receiver instance of a Receiver for process control @param spawnArgs standard and additional spawn arguments """ #logging.debug('BaseProcess.__init__()') self.procState = "UNINITIALIZED" spawnArgs = spawnArgs.copy() if spawnArgs else {} self.spawnArgs = spawnArgs self.init_time = pu.currenttime_ms() # Name (human readable label) of this process. self.procName = self.spawnArgs.get('proc-name', __name__) # The system unique ID; propagates from root supv to all child procs sysname = ioninit.cont_args.get('sysname', Container.id) self.sysName = self.spawnArgs.get('sys-name', sysname) # The process ID of the supervisor process self.procSupId = pu.get_process_id(self.spawnArgs.get('sup-id', None)) if not receiver: receiver = Receiver(self.procName) self.receiver = receiver receiver.handle(self.receive) # Dict of all receivers of this process. Key is the name self.receivers = {} self.add_receiver(self.receiver) # Dict of converations. # @todo: make sure this is garbage collected once in a while self.conversations = {} # Conversations by conv-id for currently outstanding RPCs self.rpc_conv = {} # List of ProcessDesc instances of defined and spawned child processes self.child_procs = [] logging.info("Process init'd: proc-name=%s, sup-id=%s, sys-name=%s" % ( self.procName, self.procSupId, self.sysName))