def __init__(self, myQueue, parentQ, adminQ, adminAddr): self._myInputQ = myQueue self._parentQ = parentQ self._adminQ = adminQ self._adminAddr = adminAddr # _queues is a map of direct child ActorAddresses to Queue instance. Note # that there will be multiple keys mapping to the same Queue # instance because routing is only either to the Parent or to # an immediate Child. self._queues = AssocList() # addr -> queue # _fwdvia represents routing for other than immediate parent # or child (there may be multiple target addresses mapping to # the same forward address. self._fwdvia = AssocList() # targetAddress -> fwdViaAddress self._deadaddrs = [] # Signals can set these to true; they should be checked and # reset by the main processing loop. There is a small window # where they could be missed because signals are not queued, # but this should handle the majority of situations. Note # that the Queue object is NOT signal-safe, so don't try to # queue signals that way. self._checkChildren = False self._shutdownSignalled = False
def __init__(self, transport, address, capabilities, logdefs, concurrency_context): thesplog('++++ Starting Admin from %s', sys.modules['thespian'].__file__, level=logging.DEBUG) super(AdminCore, self).__init__(address, transport) self.init_replicator(transport, concurrency_context) self.capabilities = capabilities self.logdefs = logdefs self._pendingChildren = {} # Use: childLocalAddr instance # : PendingActorEnvelope # Things that help us look like an Actor, even though we're not self._sourceHash = None thesplog('++++ Admin started @ %s / gen %s', self.transport.myAddress, str(ThespianGeneration), level=logging.INFO, primary=True) logging.info('++++ Actor System gen %s started, admin @ %s', str(ThespianGeneration), self.transport.myAddress) logging.debug('Thespian source: %s', sys.modules['thespian'].__file__) self._nannying = AssocList() # child actorAddress -> parent Address self._deadLetterHandler = None self._sources = {} # Index is sourcehash, value PendingSource or ValidSource self._sourceAuthority = None self._sourceNotifications = [] # array of notification addresses # The initialization of the Admin and its logger # occurs asynchronously, but since the Admin is using a known # address, there is nothing to prevent clients from initiating # requests to the Admin before it has had a chance to complete # the initialization; the _pre_init_msgs will hold those # requests until the initialization has completed. self._pre_init_msgs = []
def __init__(self, transport, address, capabilities, logdefs, concurrency_context): thesplog('++++ Starting Admin from %s', sys.modules['thespian'].__file__, level=logging.DEBUG) super(AdminCore, self).__init__(address, transport) self.init_replicator(transport, concurrency_context) self.capabilities = capabilities self.logdefs = logdefs self._pendingChildren = { } # Use: childLocalAddr instance # : PendingActorEnvelope # Things that help us look like an Actor, even though we're not self._sourceHash = None thesplog('++++ Admin started @ %s / gen %s', self.transport.myAddress, str(ThespianGeneration), level=logging.INFO, primary=True) logging.info('++++ Actor System gen %s started, admin @ %s', str(ThespianGeneration), self.transport.myAddress) logging.debug('Thespian source: %s', sys.modules['thespian'].__file__) self._nannying = AssocList() # child actorAddress -> parent Address self._deadLetterHandler = None self._sources = { } # Index is sourcehash, value PendingSource or ValidSource self._sourceAuthority = None self._sourceNotifications = [] # array of notification addresses
def __init__(self, address_manager): self._addrmgr = address_manager # There are expected to be a low number of pending transmits # for a typical actor. At present time, this is an array of # intents. Note that an intent may fail due to a # CannotPickleAddress (which calls cannot_send_now() ), and # then later be passed here again to can_send_now() when the # address becomes known. self._atd = AssocList() # address -> ptl index self._ptl = []
def __init__(self, *args, **kw): super(ConventioneerAdmin, self).__init__(*args, **kw) self._conventionMembers = AssocList( ) # key=Remote Admin Addr, value=ConventionMemberData self._conventionRegistration = ExpiryTime(timedelta(seconds=0)) self._conventionNotificationHandlers = [] self._conventionAddress = None # Not a member; still could be a leader self._pendingSources = { } # key = sourceHash, value is array of PendingActor requests self._hysteresisSender = HysteresisDelaySender(self._send_intent)
def __init__(self, myAddress, capabilities, sCBStats, getConventionAddressFunc): self._myAddress = myAddress self._capabilities = capabilities self._sCBStats = sCBStats self._conventionMembers = AssocList() # key=Remote Admin Addr, value=ConventionMemberData self._conventionNotificationHandlers = [] self._getConventionAddr = getConventionAddressFunc self._conventionAddress = getConventionAddressFunc(capabilities) self._conventionRegistration = ExpirationTimer(CONVENTION_REREGISTRATION_PERIOD) self._has_been_activated = False self._invited = False # entered convention as a result of an explicit invite
def __init__(self, initType, *args): super(MultiprocessQueueTransport, self).__init__() if isinstance(initType, ExternalInterfaceTransportInit): # External process that's going to talk "in". There is no # parent, and the child is the systemAdmin. capabilities, logDefs, self._concontext = args self._parentQ = None NewQ = self._concontext.Queue if self._concontext else Queue self._adminQ = NewQ(MAX_ADMIN_QUEUESIZE) self._adminAddr = self.getAdminAddr(capabilities) self._myQAddress = ActorAddress(QueueActorAddress('~')) self._myInputQ = NewQ(MAX_ACTOR_QUEUESIZE) elif isinstance(initType, MpQTEndpoint): _addrInst, myAddr, myQueue, parentQ, adminQ, adminAddr, ccon = initType.args self._concontext = ccon self._parentQ = parentQ self._adminQ = adminQ self._adminAddr = adminAddr self._myQAddress = myAddr self._myInputQ = myQueue else: thesplog('MultiprocessQueueTransport init of type %s unsupported!', str(initType), level=logging.ERROR) # _queues is a map of direct child ActorAddresses to Queue instance. Note # that there will be multiple keys mapping to the same Queue # instance because routing is only either to the Parent or to # an immediate Child. self._queues = AssocList() # addr -> queue # _fwdvia represents routing for other than immediate parent # or child (there may be multiple target addresses mapping to # the same forward address. self._fwdvia = AssocList() # targetAddress -> fwdViaAddress self._nextSubInstance = 0
def deadAddress(self, addressManager, childAddr): # Can no longer send to this Queue object. Delete the # entry; this will cause forwarding of messages, although # the addressManager is also aware of the dead address and # will cause DeadEnvelope forwarding. Deleting here # prevents hanging on queue full to dead children. self._queues.rmv(childAddr) deadfwd, okfwd = ([],[]) if False else \ partition(lambda i: i[0] == childAddr or i[1] == childAddr, self._fwdvia.items()) if deadfwd: self._fwdvia = AssocList() for A,AQ in okfwd: self._fwdvia.add(A,AQ) super(MultiprocessQueueTransport, self).deadAddress(addressManager, childAddr)