def test_spawn_child(self): child1 = ProcessDesc(name='echo', module='ion.core.test.test_baseprocess') self.assertEquals(child1.proc_state, 'DEFINED') pid1 = yield self.test_sup.spawn_child(child1) self.assertEquals(child1.proc_state, 'INIT_OK') proc = self._get_procinstance(pid1) self.assertEquals( str(proc.__class__), "<class 'ion.core.test.test_baseprocess.EchoProcess'>") self.assertEquals(pid1, proc.receiver.spawned.id) logging.info('Process 1 spawned and initd correctly') (cont, hdrs, msg) = yield self.test_sup.rpc_send(pid1, 'echo', 'content123') self.assertEquals(cont['value'], 'content123') logging.info('Process 1 responsive correctly') # The following tests the process attaching a second receiver msgName = self.test_sup.get_scoped_name('global', pu.create_guid()) messaging = {'name_type': 'worker', 'args': {'scope': 'global'}} yield Container.configure_messaging(msgName, messaging) extraRec = Receiver(proc.proc_name, msgName) extraRec.handle(proc.receive) extraid = yield spawn(extraRec) logging.info('Created new receiver %s with pid %s' % (msgName, extraid)) (cont, hdrs, msg) = yield self.test_sup.rpc_send(msgName, 'echo', 'content456') self.assertEquals(cont['value'], 'content456') logging.info('Process 1 responsive correctly on second receiver')
def plc_init(self): yield self._declare_service_name() svcid = yield spawn(self.svc_receiver) logging.info('Service process bound to name=%s as pid=%s' % (self.svc_receiver.name, svcid)) yield defer.maybeDeferred(self.slc_init) yield defer.maybeDeferred(self.slc_start)
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 setUp(self): yield self._start_container() bproc = BaseProcess() # the 'test' work queue: self.queue_name_work = bproc.get_scoped_name("system", "test_cei_sensors_work") # for the sensor events queue: self.queue_name_events = bproc.get_scoped_name("system", "test_cei_sensors_events") self.total_messages = 5 topic = { self.queue_name_work: {"name_type": "worker", "args": {"scope": "global"}}, self.queue_name_events: {"name_type": "fanout", "args": {"scope": "global"}}, } yield self._declare_messaging(topic) # create a test SA: self.test_sa = TestSensorAggregator(self.queue_name_events) # now spawn it: sa_id = yield spawn(self.test_sa.receiver) yield self.test_sa.plc_init() services = [ { "name": "rabbitmq_sensor", "module": "ion.services.cei.sensors.rabbitmq_sensor", "spawnargs": {"queue_name_work": self.queue_name_work, "queue_name_events": self.queue_name_events}, } ] self.sup = yield self._spawn_processes(services) self.rabbitmq_sensor = self.sup.get_child_id("rabbitmq_sensor") for i in range(self.total_messages): yield self.sup.send(self.queue_name_work, "data", "test_message" + str(i))
def test_message_during_init(self): child2 = ProcessDesc(name='echo', module='ion.core.test.test_baseprocess') pid2 = yield self.test_sup.spawn_child(child2, init=False) proc2 = self._get_procinstance(pid2) proc2.plc_init = proc2.plc_noinit self.assertEquals(proc2.proc_state, 'NEW') msgName = self.test_sup.get_scoped_name('global', pu.create_guid()) messaging = {'name_type':'worker', 'args':{'scope':'global'}} yield Container.configure_messaging(msgName, messaging) extraRec = Receiver(proc2.proc_name, msgName) extraRec.handle(proc2.receive) extraid = yield spawn(extraRec) logging.info('Created new receiver %s with pid %s' % (msgName, extraid)) yield self.test_sup.send(pid2, 'init',{},{'quiet':True}) logging.info('Sent init to process 1') yield pu.asleep(0.5) self.assertEquals(proc2.proc_state, 'INIT') (cont,hdrs,msg) = yield self.test_sup.rpc_send(msgName,'echo','content123') self.assertEquals(cont['value'], 'content123') logging.info('Process 1 responsive correctly after init') yield pu.asleep(2) self.assertEquals(proc2.proc_state, 'ACTIVE') (cont,hdrs,msg) = yield self.test_sup.rpc_send(msgName,'echo','content123') self.assertEquals(cont['value'], 'content123') logging.info('Process 1 responsive correctly after init')
def test_message_during_init(self): child2 = ProcessDesc(name='echo', module='ion.core.test.test_baseprocess') pid2 = yield self.test_sup.spawn_child(child2, init=False) proc2 = self._get_procinstance(pid2) proc2.plc_init = proc2.plc_noinit self.assertEquals(proc2.proc_state, 'NEW') msgName = self.test_sup.get_scoped_name('global', pu.create_guid()) messaging = {'name_type': 'worker', 'args': {'scope': 'global'}} yield Container.configure_messaging(msgName, messaging) extraRec = Receiver(proc2.proc_name, msgName) extraRec.handle(proc2.receive) extraid = yield spawn(extraRec) logging.info('Created new receiver %s with pid %s' % (msgName, extraid)) yield self.test_sup.send(pid2, 'init', {}, {'quiet': True}) logging.info('Sent init to process 1') yield pu.asleep(0.5) self.assertEquals(proc2.proc_state, 'INIT') (cont, hdrs, msg) = yield self.test_sup.rpc_send(msgName, 'echo', 'content123') self.assertEquals(cont['value'], 'content123') logging.info('Process 1 responsive correctly after init') yield pu.asleep(2) self.assertEquals(proc2.proc_state, 'ACTIVE') (cont, hdrs, msg) = yield self.test_sup.rpc_send(msgName, 'echo', 'content123') self.assertEquals(cont['value'], 'content123') logging.info('Process 1 responsive correctly after init')
def spawn(self, supProc=None): """ Spawns this process description with the initialized attributes. @param supProc the process instance that should be set as supervisor """ assert self.procState == 'DEFINED', "Cannot spawn process twice" self.supProcess = supProc if self.procNode == None: logging.info('Spawning name=%s node=%s' % (self.procName, self.procNode)) # Importing service module proc_mod = pu.get_module(self.procModule) self.procModObj = proc_mod # Spawn instance of a process # During spawn, the supervisor process id, system name and proc name # get provided as spawn args, in addition to any give spawn args. spawnargs = {'proc-name':self.procName, 'sup-id':self.supProcess.receiver.spawned.id.full, 'sys-name':self.supProcess.sysName} if self.spawnArgs: spawnargs.update(self.spawnArgs) #logging.debug("spawn(%s, args=%s)" % (self.procModule, spawnargs)) proc_id = yield spawn(proc_mod, None, spawnargs) self.procId = proc_id self.procState = 'SPAWNED' #logging.info("Process "+self.procClass+" ID: "+str(proc_id)) else: logging.error('Cannot spawn '+self.procClass+' on node='+str(self.procNode)) defer.returnValue(self.procId)
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 test_fanout(self): messaging = {'fanout1':{'name_type':'fanout', 'args':{'scope':'local'}}} workers = [ {'name':'fanoutProc1','module':'ion.core.worker','class':'WorkerProcess','spawnargs':{'service-name':'fanout1','scope':'local'}}, {'name':'fanoutProc2','module':'ion.core.worker','class':'WorkerProcess','spawnargs':{'service-name':'fanout1','scope':'local'}}, ] yield self._declare_messaging(messaging) yield self._spawn_processes(workers) sup = yield self._get_procid("bootstrap") logging.info("Supervisor: "+repr(sup)) wc = WorkerClient() wcId = yield spawn(wc.receiver) wq_name = Container.id + ".fanout1" for i in range(1,6): yield wc.submit_work(wq_name, i, 0.5) yield pu.asleep(5) logging.info("Work results: "+str(wc.workresult)) logging.info("Worker results: "+str(wc.worker)) sum = 0 for w,v in wc.worker.items(): sum += v self.assertEqual(sum, 10)
def test_spawn_child(self): child1 = ProcessDesc(name='echo', module='ion.core.test.test_baseprocess') self.assertEquals(child1.proc_state,'DEFINED') pid1 = yield self.test_sup.spawn_child(child1) self.assertEquals(child1.proc_state,'INIT_OK') proc = self._get_procinstance(pid1) self.assertEquals(str(proc.__class__),"<class 'ion.core.test.test_baseprocess.EchoProcess'>") self.assertEquals(pid1, proc.receiver.spawned.id) logging.info('Process 1 spawned and initd correctly') (cont,hdrs,msg) = yield self.test_sup.rpc_send(pid1,'echo','content123') self.assertEquals(cont['value'], 'content123') logging.info('Process 1 responsive correctly') # The following tests the process attaching a second receiver msgName = self.test_sup.get_scoped_name('global', pu.create_guid()) messaging = {'name_type':'worker', 'args':{'scope':'global'}} yield Container.configure_messaging(msgName, messaging) extraRec = Receiver(proc.proc_name, msgName) extraRec.handle(proc.receive) extraid = yield spawn(extraRec) logging.info('Created new receiver %s with pid %s' % (msgName, extraid)) (cont,hdrs,msg) = yield self.test_sup.rpc_send(msgName,'echo','content456') self.assertEquals(cont['value'], 'content456') logging.info('Process 1 responsive correctly on second receiver')
def plc_init(self): # create new receiver ('listener'), for the events (just the receiver object) self.event_receiver = Receiver("event_receiver", self.queue_name_events) # set BaseProcesses receive method as the callback for the new receiver that was just created. self.event_receiver.handle(self.receive) # actually create queue consumer: receiver_id = yield spawn(self.event_receiver)
def attach(self, topic_name): self.dataReceiver = Receiver(__name__, topic_name) self.dataReceiver.handle(self.receive) self.dr_id = yield spawn(self.dataReceiver) logging.info("DataConsumer.attach " + str(self.dr_id) + " to topic " + str(topic_name)) self.receive_cnt = 0 self.received_msg = [] self.ondata = None
def spawn(self): """ Spawns this process using the process' receiver. Self spawn can only be called once per instance. @note this method is not called when spawned by magnet """ assert not self.receiver.spawned, "Process already spawned" self.id = yield spawn(self.receiver) logging.debug('spawn()=' + str(self.id)) defer.returnValue(self.id)
def attach(self, topic_name): """ Attach to the given topic name """ yield self.init() self.dataReceiver = Receiver(__name__, topic_name) self.dataReceiver.handle(self.receive) self.dr_id = yield spawn(self.dataReceiver) self.receive_cnt = 0 self.received_msg = [] self.ondata = None
def slc_init(self): msg_name = self.spawn_args['service-name'] scope = self.spawn_args['scope'] logging.info("slc_init name received:" + msg_name) msg_name1 = self.get_scoped_name(scope, msg_name) logging.info("slc_init name used:" + msg_name1) workReceiver = Receiver(__name__, msg_name1) self.workReceiver = workReceiver self.workReceiver.handle(self.receive) logging.info("slc_init worker receiver spawning") id = yield spawn(workReceiver) logging.info("slc_init worker receiver spawned:" + str(id))
def slc_init(self): msg_name = self.spawn_args['service-name'] scope = self.spawn_args['scope'] logging.info("slc_init name received:"+msg_name) msg_name1 = self.get_scoped_name(scope, msg_name) logging.info("slc_init name used:"+msg_name1) workReceiver = Receiver(__name__, msg_name1) self.workReceiver = workReceiver self.workReceiver.handle(self.receive) logging.info("slc_init worker receiver spawning") id = yield spawn(workReceiver) logging.info("slc_init worker receiver spawned:"+str(id))
def attach(self, queue): #@Note - I tried to put a try/except here, but it did not catch the error from magnet # Check and make sure it is not already attached? dataReceiver = Receiver(__name__, str(queue)) dataReceiver.handle(self.receive) dr_id = yield spawn(dataReceiver) #print dr_id, dataReceiver.name self.dataReceivers[dataReceiver.name] = dataReceiver self.receive_cnt[queue]=0 logging.info("DataConsumer.attach "+str(dr_id)+" to topic "+str(queue)) defer.returnValue(dr_id)
@file ion/core/supervisor.py @author Michael Meisinger @brief base class for processes that supervise other processes """ import logging logging = logging.getLogger(__name__) from twisted.internet import defer from magnet.spawnable import spawn from ion.core.base_process import BaseProcess, ProtocolFactory import ion.util.procutils as pu class Supervisor(BaseProcess): """ Base class for a supervisor process. A supervisor is a process with the purpose to monitor child processes and to restart them in case of failure. Spawing child processes is a function of the BaseProcess itself. """ def event_failure(self): return # Spawn of the process using the module name factory = ProtocolFactory(Supervisor) """ from ion.core import supervisor as s spawn(s) """