def testMainAddressRevocation(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) addr = ActorAddress(id(self)) am.deadAddress(addr) assert addr == am.sendToAddress(addr) assert am.isDeadAddress(addr)
def testGetUniqueLocalAddresses(self): am = ActorAddressManager(None, "an address") addr1 = am.createLocalAddress() addr2 = am.createLocalAddress() assert addr1 != addr2 assert addr2 != addr1 assert addr1 == addr1 assert addr2 == addr2
def testMakeAssociation(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr = ActorAddress(id(self)) am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) # No exception thrown assert True
def __init__(self, adminAddr, transport): self._adminAddr = adminAddr self.transport = transport self._addrManager = ActorAddressManager(adminAddr, self.transport.myAddress) self.transport.setAddressManager(self._addrManager) self._pendingTransmits = PendingTransmits(self._addrManager) self._awaitingAddressUpdate = AddressWaitTransmits() self._receiveQueue = [] # array of ReceiveMessage to be processed self._children = [] # array of Addresses of children of this Actor/Admin self._governer = RateThrottle(RATE_THROTTLE) self._sCBStats = StatsManager()
def testAssociationStillNotHashable(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr = ActorAddress(id(self)) raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr) am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr)
def testAssociationEquality(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr = ActorAddress(id(self)) assert lclAddr != mainAddr assert mainAddr != lclAddr am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) assert lclAddr == mainAddr assert mainAddr == lclAddr
def __init__(self, adminAddr, transport): self._adminAddr = adminAddr self.transport = transport self._addrManager = ActorAddressManager(adminAddr, self.transport.myAddress) self.transport.setAddressManager(self._addrManager) self._finalTransmitPending = { } # key = target ActorAddress, value=None or the last pending Intent self._awaitingAddressUpdate = { } # key = actorAddress waited on (usually local), value=array of transmit Intents self._receiveQueue = [] # array of ReceiveMessage to be processed self._children = [ ] # array of Addresses of children of this Actor/Admin self._governer = RateThrottle(RATE_THROTTLE) self._sCBStats = StatsManager()
def testAssociatedAddressesDoNotMatchArbitraryStuff(self): myAddress = 'my addr' am = ActorAddressManager(None, myAddress) lclAddr1, mainAddr1 = self._makeLocalAndAssociated(myAddress, am) assert None != lclAddr1 assert id(self) != lclAddr1 assert 0 != lclAddr1 assert "hi" != lclAddr1 assert SomeRandomObject != lclAddr1 assert None != mainAddr1 assert id(self) != mainAddr1 assert 0 != mainAddr1 assert "hi" != mainAddr1 assert SomeRandomObject != mainAddr1 assert lclAddr1 != None assert lclAddr1 != id(self) assert lclAddr1 != 0 assert lclAddr1 != "hi" assert lclAddr1 != SomeRandomObject assert mainAddr1 != None assert mainAddr1 != id(self) assert mainAddr1 != 0 assert mainAddr1 != "hi" assert mainAddr1 != SomeRandomObject
def testLocalAddressRevocation(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lcladdr = am.createLocalAddress() am.deadAddress(lcladdr) assert am.sendToAddress(lcladdr) is None assert am.isDeadAddress(lcladdr) assert lcladdr == am.getLocalAddress( lcladdr.addressDetails.addressInstanceNum)
class TestAddressManagerLocalAddresses(unittest.TestCase): scope='unit' def setUp(self): self.myAddress = 'me' self.am = ActorAddressManager(None, self.myAddress) def testGetValidLocalAddress(self): addr = self.am.createLocalAddress() self.assertIsInstance(addr.addressDetails, ActorLocalAddress) def testGetUniqueLocalAddresses(self): addr1 = self.am.createLocalAddress() addr2 = self.am.createLocalAddress() self.assertNotEqual(addr1, addr2) self.assertNotEqual(addr2, addr1) self.assertEqual(addr1, addr1) self.assertEqual(addr2, addr2) def testLocalAddressCannotBePickled(self): self.am = ActorAddressManager(None, 'me') addr = self.am.createLocalAddress() self.assertRaises(CannotPickleAddress, pickle.dumps, addr) def testLocalAddressCanBeReconstituted(self): addr = self.am.createLocalAddress() addr2 = self.am.getLocalAddress(addr.addressDetails.addressInstanceNum) self.assertEqual(addr, addr2) def testLocalAddressCannotBeUsedForSending(self): addr = self.am.createLocalAddress() self.assertIsNone(self.am.sendToAddress(addr))
def testAssociationHashEqualityWithReconstitutedNonLocalAddress(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr1 = ActorAddress(None) mainAddr2 = ActorAddress(9) assert mainAddr1 != mainAddr2 raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr1) raises(TypeError, hash, mainAddr2) am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr1) raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr1) raises(TypeError, hash, mainAddr2) mainAddr1_dup = ActorAddress(None) assert mainAddr1 == mainAddr1_dup raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr1) raises(TypeError, hash, mainAddr1_dup) raises(TypeError, hash, mainAddr2) am.importAddr(mainAddr1_dup) raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr1) raises(TypeError, hash, mainAddr1_dup) raises(TypeError, hash, mainAddr2)
class TestAddressManagerLocalAddresses(unittest.TestCase): scope = 'unit' def setUp(self): self.myAddress = 'me' self.am = ActorAddressManager(None, self.myAddress) def testGetValidLocalAddress(self): addr = self.am.createLocalAddress() self.assertIsInstance(addr.addressDetails, ActorLocalAddress) def testGetUniqueLocalAddresses(self): addr1 = self.am.createLocalAddress() addr2 = self.am.createLocalAddress() self.assertNotEqual(addr1, addr2) self.assertNotEqual(addr2, addr1) self.assertEqual(addr1, addr1) self.assertEqual(addr2, addr2) def testLocalAddressCannotBePickled(self): self.am = ActorAddressManager(None, 'me') addr = self.am.createLocalAddress() self.assertRaises(CannotPickleAddress, pickle.dumps, addr) def testLocalAddressCanBeReconstituted(self): addr = self.am.createLocalAddress() addr2 = self.am.getLocalAddress(addr.addressDetails.addressInstanceNum) self.assertEqual(addr, addr2) def testLocalAddressCannotBeUsedForSending(self): addr = self.am.createLocalAddress() self.assertIsNone(self.am.sendToAddress(addr))
def testAssociationEqualityWithReconstitutedNonLocalAddress(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr1 = ActorAddress(None) mainAddr2 = ActorAddress(9) assert mainAddr1 != mainAddr2 am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr1) assert lclAddr == mainAddr1 assert mainAddr1 == lclAddr assert lclAddr != mainAddr2 assert mainAddr2 != lclAddr mainAddr1_dup = ActorAddress(None) assert mainAddr1 == mainAddr1_dup assert mainAddr1_dup == lclAddr assert lclAddr == mainAddr1_dup am.importAddr(mainAddr1_dup) assert mainAddr1_dup == lclAddr assert lclAddr == mainAddr1_dup assert mainAddr1_dup == mainAddr1
def __init__(self, adminAddr, transport): self._adminAddr = adminAddr self.transport = transport self._addrManager = ActorAddressManager(adminAddr, self.transport.myAddress) self.transport.setAddressManager(self._addrManager) self._finalTransmitPending = {} # key = target ActorAddress, value=None or the last pending Intent self._awaitingAddressUpdate = {} # key = actorAddress waited on (usually local), value=array of transmit Intents self._receiveQueue = [] # array of ReceiveMessage to be processed self._children = [] # array of Addresses of children of this Actor/Admin self._governer = RateThrottle(RATE_THROTTLE) self._sCBStats = StatsManager()
def testAssociatedAddressEqualityIsUnique(self): myAddress = 'thisaddr' am = ActorAddressManager(None, myAddress) lclAddr1, mainAddr1 = self._makeLocalAndAssociated(myAddress, am) print('Set 1: %s --> %s' % (str(lclAddr1), str(mainAddr1))) lclAddr2, mainAddr2 = self._makeLocalAndAssociated(myAddress, am) print('Set 2: %s --> %s' % (str(lclAddr2), str(mainAddr2))) lclAddr3, mainAddr3 = self._makeLocalAndAssociated(myAddress, am) print('Set 3: %s --> %s' % (str(lclAddr3), str(mainAddr3))) assert lclAddr1 == lclAddr1 assert lclAddr2 == lclAddr2 assert lclAddr3 == lclAddr3 assert mainAddr1 == mainAddr1 assert mainAddr2 == mainAddr2 assert mainAddr3 == mainAddr3 assert lclAddr1 == mainAddr1 assert lclAddr2 == mainAddr2 assert lclAddr3 == mainAddr3 assert mainAddr1 == lclAddr1 assert mainAddr2 == lclAddr2 assert mainAddr3 == lclAddr3 assert lclAddr1 != lclAddr2 assert lclAddr2 != lclAddr1 assert lclAddr3 != lclAddr2 assert lclAddr2 != lclAddr3 assert lclAddr3 != lclAddr1 assert lclAddr1 != lclAddr3 assert mainAddr1 != mainAddr2 assert mainAddr2 != mainAddr1 assert mainAddr3 != mainAddr2 assert mainAddr2 != mainAddr3 assert mainAddr3 != mainAddr1 assert mainAddr1 != mainAddr3 assert mainAddr1 != lclAddr2 assert mainAddr2 != lclAddr1 assert mainAddr3 != lclAddr2 assert mainAddr2 != lclAddr3 assert mainAddr3 != lclAddr1 assert mainAddr1 != lclAddr3 assert lclAddr1 != mainAddr2 assert lclAddr2 != mainAddr1 assert lclAddr3 != mainAddr2 assert lclAddr2 != mainAddr3 assert lclAddr3 != mainAddr1 assert lclAddr1 != mainAddr3
def testLocalAddressCanBeReconstituted(self): am = ActorAddressManager(None, "my own: address") addr = am.createLocalAddress() addr2 = am.getLocalAddress(addr.addressDetails.addressInstanceNum) assert addr == addr2
def testAssociationNotRequiredForUseableNonLocal(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) addr = ActorAddress(id(self)) assert addr == am.sendToAddress(addr)
def testAssociationUnique(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) self.testAssociationRemembered() lclAddr2 = am.createLocalAddress() assert am.sendToAddress(lclAddr2) is None
def testAssociationRemembered(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr, mainAddr = self._makeLocalAndAssociated(myAddress, am) assert mainAddr == am.sendToAddress(lclAddr) assert mainAddr == am.sendToAddress(mainAddr)
def testLocalAddressCannotBeUsedForSending(self): am = ActorAddressManager(None, "here") addr = am.createLocalAddress() assert am.sendToAddress(addr) is None
def testNonLocalAddressRevocationAssociation(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr, mainAddr = self._makeLocalAndAssociated(myAddress, am) am.deadAddress(mainAddr) assert mainAddr == am.sendToAddress(lclAddr) assert mainAddr == am.sendToAddress(mainAddr) assert am.isDeadAddress(lclAddr) assert am.isDeadAddress(mainAddr) assert am.isDeadAddress(am.sendToAddress(mainAddr)) assert am.isDeadAddress(am.sendToAddress(lclAddr))
def testAssociatedAddressRevocationIsUnique(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr1, mainAddr1 = self._makeLocalAndAssociated(myAddress, am) print('1', str(lclAddr1), str(mainAddr1)) lclAddr2, mainAddr2 = self._makeLocalAndAssociated(myAddress, am) print('2', str(lclAddr2), str(mainAddr2)) lclAddr3, mainAddr3 = self._makeLocalAndAssociated(myAddress, am) print('3', str(lclAddr3), str(mainAddr3)) assert not am.isDeadAddress(lclAddr1) assert not am.isDeadAddress(mainAddr1) print('1sm', str(am.sendToAddress(mainAddr1))) assert not am.isDeadAddress(am.sendToAddress(mainAddr1)) print('1sl', str(am.sendToAddress(lclAddr1))) assert not am.isDeadAddress(am.sendToAddress(lclAddr1)) assert not am.isDeadAddress(lclAddr2) assert not am.isDeadAddress(mainAddr2) assert not am.isDeadAddress(am.sendToAddress(mainAddr2)) assert not am.isDeadAddress(am.sendToAddress(lclAddr2)) assert not am.isDeadAddress(lclAddr3) assert not am.isDeadAddress(mainAddr3) assert not am.isDeadAddress(am.sendToAddress(mainAddr3)) assert not am.isDeadAddress(am.sendToAddress(lclAddr3)) am.deadAddress(lclAddr1) am.deadAddress(mainAddr2) assert am.isDeadAddress(lclAddr1) assert am.isDeadAddress(mainAddr1) assert am.isDeadAddress(am.sendToAddress(mainAddr1)) assert am.isDeadAddress(am.sendToAddress(lclAddr1)) assert am.isDeadAddress(lclAddr2) assert am.isDeadAddress(mainAddr2) assert am.isDeadAddress(am.sendToAddress(mainAddr2)) assert am.isDeadAddress(am.sendToAddress(lclAddr2)) assert not am.isDeadAddress(lclAddr3) assert not am.isDeadAddress(mainAddr3) assert not am.isDeadAddress(am.sendToAddress(mainAddr3)) assert not am.isDeadAddress(am.sendToAddress(lclAddr3))
def testAssociatedAddressRevocationIsUnique(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr1, mainAddr1 = self._makeLocalAndAssociated(myAddress, am) print('1',str(lclAddr1),str(mainAddr1)) lclAddr2, mainAddr2 = self._makeLocalAndAssociated(myAddress, am) print('2',str(lclAddr2),str(mainAddr2)) lclAddr3, mainAddr3 = self._makeLocalAndAssociated(myAddress, am) print('3',str(lclAddr3),str(mainAddr3)) assert not am.isDeadAddress(lclAddr1) assert not am.isDeadAddress(mainAddr1) print('1sm',str(am.sendToAddress(mainAddr1))) assert not am.isDeadAddress(am.sendToAddress(mainAddr1)) print('1sl',str(am.sendToAddress(lclAddr1))) assert not am.isDeadAddress(am.sendToAddress(lclAddr1)) assert not am.isDeadAddress(lclAddr2) assert not am.isDeadAddress(mainAddr2) assert not am.isDeadAddress(am.sendToAddress(mainAddr2)) assert not am.isDeadAddress(am.sendToAddress(lclAddr2)) assert not am.isDeadAddress(lclAddr3) assert not am.isDeadAddress(mainAddr3) assert not am.isDeadAddress(am.sendToAddress(mainAddr3)) assert not am.isDeadAddress(am.sendToAddress(lclAddr3)) am.deadAddress(lclAddr1) am.deadAddress(mainAddr2) assert am.isDeadAddress(lclAddr1) assert am.isDeadAddress(mainAddr1) assert am.isDeadAddress(am.sendToAddress(mainAddr1)) assert am.isDeadAddress(am.sendToAddress(lclAddr1)) assert am.isDeadAddress(lclAddr2) assert am.isDeadAddress(mainAddr2) assert am.isDeadAddress(am.sendToAddress(mainAddr2)) assert am.isDeadAddress(am.sendToAddress(lclAddr2)) assert not am.isDeadAddress(lclAddr3) assert not am.isDeadAddress(mainAddr3) assert not am.isDeadAddress(am.sendToAddress(mainAddr3)) assert not am.isDeadAddress(am.sendToAddress(lclAddr3))
class TestAddressManagerLocalAddressAssociations(unittest.TestCase): scope='unit' def setUp(self): self.myAddress = 'me' self.am = ActorAddressManager(None, self.myAddress) def testMakeAssociation(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(self)) self.am.associateUseableAddress(self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) # No exception thrown self.assertTrue(True) def _makeLocalAndAssociated(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(lclAddr)) self.am.associateUseableAddress(self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) return lclAddr, mainAddr def testAssociationRemembered(self): lclAddr, mainAddr = self._makeLocalAndAssociated() self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr)) self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr)) def testAssociationUnique(self): self.testAssociationRemembered() lclAddr2 = self.am.createLocalAddress() self.assertIsNone(self.am.sendToAddress(lclAddr2)) def testAssociationNotRequiredForUseableNonLocal(self): addr = ActorAddress(id(self)) self.assertEqual(addr, self.am.sendToAddress(addr)) def testAssociationEquality(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(self)) self.assertNotEqual(lclAddr, mainAddr) self.assertNotEqual(mainAddr, lclAddr) self.am.associateUseableAddress(self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) self.assertEqual(lclAddr, mainAddr) self.assertEqual(mainAddr, lclAddr) def testAssociationEqualityWithReconstitutedNonLocalAddress(self): lclAddr = self.am.createLocalAddress() mainAddr1 = ActorAddress(None) mainAddr2 = ActorAddress(9) self.assertNotEqual(mainAddr1, mainAddr2) self.am.associateUseableAddress(self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr1) self.assertEqual(lclAddr, mainAddr1) self.assertEqual(mainAddr1, lclAddr) self.assertNotEqual(lclAddr, mainAddr2) self.assertNotEqual(mainAddr2, lclAddr) mainAddr1_dup = ActorAddress(None) self.assertEqual(mainAddr1, mainAddr1_dup) self.assertNotEqual(mainAddr1_dup, lclAddr) self.assertEqual(lclAddr, mainAddr1_dup) self.am.importAddr(mainAddr1_dup) self.assertEqual(mainAddr1_dup, lclAddr) self.assertEqual(lclAddr, mainAddr1_dup) self.assertEqual(mainAddr1_dup, mainAddr1) def testAssociatedAddressesDoNotMatchArbitraryStuff(self): lclAddr1, mainAddr1 = self._makeLocalAndAssociated() self.assertNotEqual(None, lclAddr1) self.assertNotEqual(id(self), lclAddr1) self.assertNotEqual(0, lclAddr1) self.assertNotEqual("hi", lclAddr1) self.assertNotEqual(unittest.TestCase, lclAddr1) self.assertNotEqual(None, mainAddr1) self.assertNotEqual(id(self), mainAddr1) self.assertNotEqual(0, mainAddr1) self.assertNotEqual("hi", mainAddr1) self.assertNotEqual(unittest.TestCase, mainAddr1) self.assertNotEqual(lclAddr1, None) self.assertNotEqual(lclAddr1, id(self)) self.assertNotEqual(lclAddr1, 0) self.assertNotEqual(lclAddr1, "hi") self.assertNotEqual(lclAddr1, unittest.TestCase) self.assertNotEqual(mainAddr1, None) self.assertNotEqual(mainAddr1, id(self)) self.assertNotEqual(mainAddr1, 0) self.assertNotEqual(mainAddr1, "hi") self.assertNotEqual(mainAddr1, unittest.TestCase) def testAssociatedAddressEqualityIsUnique(self): lclAddr1, mainAddr1 = self._makeLocalAndAssociated() print('Set 1: %s --> %s'%(str(lclAddr1), str(mainAddr1))) lclAddr2, mainAddr2 = self._makeLocalAndAssociated() print('Set 2: %s --> %s'%(str(lclAddr2), str(mainAddr2))) lclAddr3, mainAddr3 = self._makeLocalAndAssociated() print('Set 3: %s --> %s'%(str(lclAddr3), str(mainAddr3))) self.assertEqual(lclAddr1, lclAddr1) self.assertEqual(lclAddr2, lclAddr2) self.assertEqual(lclAddr3, lclAddr3) self.assertEqual(mainAddr1, mainAddr1) self.assertEqual(mainAddr2, mainAddr2) self.assertEqual(mainAddr3, mainAddr3) self.assertEqual(lclAddr1, mainAddr1) self.assertEqual(lclAddr2, mainAddr2) self.assertEqual(lclAddr3, mainAddr3) self.assertEqual(mainAddr1, lclAddr1) self.assertEqual(mainAddr2, lclAddr2) self.assertEqual(mainAddr3, lclAddr3) self.assertNotEqual(lclAddr1, lclAddr2) self.assertNotEqual(lclAddr2, lclAddr1) self.assertNotEqual(lclAddr3, lclAddr2) self.assertNotEqual(lclAddr2, lclAddr3) self.assertNotEqual(lclAddr3, lclAddr1) self.assertNotEqual(lclAddr1, lclAddr3) self.assertNotEqual(mainAddr1, mainAddr2) self.assertNotEqual(mainAddr2, mainAddr1) self.assertNotEqual(mainAddr3, mainAddr2) self.assertNotEqual(mainAddr2, mainAddr3) self.assertNotEqual(mainAddr3, mainAddr1) self.assertNotEqual(mainAddr1, mainAddr3) self.assertNotEqual(mainAddr1, lclAddr2) self.assertNotEqual(mainAddr2, lclAddr1) self.assertNotEqual(mainAddr3, lclAddr2) self.assertNotEqual(mainAddr2, lclAddr3) self.assertNotEqual(mainAddr3, lclAddr1) self.assertNotEqual(mainAddr1, lclAddr3) self.assertNotEqual(lclAddr1, mainAddr2) self.assertNotEqual(lclAddr2, mainAddr1) self.assertNotEqual(lclAddr3, mainAddr2) self.assertNotEqual(lclAddr2, mainAddr3) self.assertNotEqual(lclAddr3, mainAddr1) self.assertNotEqual(lclAddr1, mainAddr3)
def testLocalAddressCannotBePickled(self): am = ActorAddressManager(None, 'me') addr = am.createLocalAddress() raises(CannotPickleAddress, pickle.dumps, addr)
def testGetValidLocalAddress(self): am = ActorAddressManager(None, "self.myAddress") addr = am.createLocalAddress() assert isinstance(addr.addressDetails, ActorLocalAddress)
def testGetValidLocalAddress(self): am = ActorAddressManager(None, "I am me") addr = ActorAddress(ActorLocalAddress('I am me', 12, am)) assert isinstance(addr.addressDetails, ActorLocalAddress)
def setUp(self): self.myAddress = 'me' self.am = ActorAddressManager(None, self.myAddress)
class systemCommonBase(object): def __init__(self, adminAddr, transport): self._adminAddr = adminAddr self.transport = transport self._addrManager = ActorAddressManager(adminAddr, self.transport.myAddress) self.transport.setAddressManager(self._addrManager) self._finalTransmitPending = {} # key = target ActorAddress, value=None or the last pending Intent self._awaitingAddressUpdate = {} # key = actorAddress waited on (usually local), value=array of transmit Intents self._receiveQueue = [] # array of ReceiveMessage to be processed self._children = [] # array of Addresses of children of this Actor/Admin self._governer = RateThrottle(RATE_THROTTLE) self._sCBStats = StatsManager() @property def address(self): return self.transport.myAddress @property def myAddress(self): return self.transport.myAddress @property def childAddresses(self): return self._children def _registerChild(self, childAddress): self._children.append(childAddress) def _handleChildExited(self, childAddress): self._sCBStats.inc('Common.Message Received.Child Actor Exited') self._addrManager.deadAddress(childAddress) self.transport.deadAddress(self._addrManager, childAddress) self._childExited(childAddress) self._children = [C for C in self._children if C != childAddress] if hasattr(self, '_exiting') and not self._children: # OK, all children are dead, can now exit this actor, but # make sure this final cleanup only occurs once # (e.g. transport.deadAddress above could recurse through # here as well. if not hasattr(self, '_exitedAlready'): self._exitedAlready = True self._sayGoodbye() self.transport.abort_run(drain=True) return True def _updateStatusResponse(self, resp): "Called to update a Thespian_SystemStatus or Thespian_ActorStatus with common information" for each in self.childAddresses: resp.addChild(each) for each in self._receiveQueue: resp.addReceivedMessage(each.sender, self.myAddress, each.message) self._sCBStats.copyToStatusResponse(resp) # Need to show _finalTransmitPending? where is head of chain? shown by transport? (no) resp.governer = str(self._governer) for addr in self._awaitingAddressUpdate: resp.addTXPendingAddressCount(addr, len(self._awaitingAddressUpdate[addr])) self.transport._updateStatusResponse(resp) def setLoggingControls(self, envelope): from thespian.system.utilis import thesplog_control msg = envelope.message thesplog_control(msg.threshold, msg.useLogging, msg.useFile) return True # ---------------------------------------------------------------------- # Transmit management def _send_intent(self, intent): self._governer.eventRatePause() # Check if there are any existing transmits in progress to # this address (on either the input address or the validated # address); if so, just add the new one to the list and # return. sendAddr = self._addrManager.sendToAddress(intent.targetAddr) finalIntent = self._finalTransmitPending.get( intent.targetAddr, self._finalTransmitPending.get(sendAddr, None)) self._finalTransmitPending[sendAddr or intent.targetAddr] = intent if finalIntent: finalIntent.nextIntent = intent self._sCBStats.inc('Actor.Message Send.Added to End of Sends') return self._send_intent_to_transport(intent) def _retryPendingChildOperations(self, childInstance, actualAddress): # actualAddress will be none if the child could not be created lcladdr = self._addrManager.getLocalAddress(childInstance) if not actualAddress: self._receiveQueue.append(ReceiveEnvelope(lcladdr, ChildActorExited(lcladdr))) if lcladdr in self._finalTransmitPending: # KWQ: what to do when actualAddress is None? self._finalTransmitPending[actualAddress] = self._finalTransmitPending[lcladdr] del self._finalTransmitPending[lcladdr] if lcladdr in self._awaitingAddressUpdate: pending = self._awaitingAddressUpdate[lcladdr] del self._awaitingAddressUpdate[lcladdr] for each in pending: if actualAddress: # KWQ: confirm the following two lines can be removed; send_intent_to_transport should do this translation on its own. At that point, the changeTargetAddr method should be able to be removed. # if each.targetAddr == lcladdr: # each.changeTargetAddr(actualAddress) self._sCBStats.inc('Actor.Message Send.Transmit ReInitiated') self._send_intent(each) else: if not isinstance(each.message, PoisonMessage): self._receiveQueue.append( ReceiveEnvelope(self.myAddress, PoisonMessage(each.message))) self._sCBStats.inc('Actor.Message Send.Poison Return on Child Abort') each.result = SendStatus.Failed each.completionCallback() def _send_intent_to_transport(self, intent): thesplog('Attempting intent %s', intent.identify(), level=logging.DEBUG) if not hasattr(intent, '_addedCheckNextTransmitCB'): intent.addCallback(self._checkNextTransmit, self._checkNextTransmit) # Protection against duplicate callback additions in case # of a retry due to the CannotPickleAddress exception below. intent._addedCheckNextTransmitCB = True try: self.transport.scheduleTransmit(self._addrManager, intent) self._sCBStats.inc('Actor.Message Send.Transmit Started') except CannotPickleAddress as ex: thesplog('CannotPickleAddress, appending intent for %s (hash=%s)', ex.address, hash(ex.address), level=logging.DEBUG) self._awaitingAddressUpdate.setdefault(ex.address, []).append(intent) self._sCBStats.inc('Actor.Message Send.Postponed for Address') self._checkNextTransmit(0, intent) except Exception: import traceback thesplog('Declaring transmit of %s as Poison: %s', intent.identify(), traceback.format_exc(), exc_info=True, level=logging.ERROR) if not isinstance(intent.message, PoisonMessage): self._receiveQueue.append(ReceiveEnvelope(intent.targetAddr, PoisonMessage(intent.message))) self._sCBStats.inc('Actor.Message Send.Transmit Poison Rejection') intent.result = SendStatus.Failed intent.completionCallback() def _checkNextTransmit(self, result, completedIntent): # This is the callback for (all) TransmitIntents that will # send the next queued intent for that destination. if completedIntent.nextIntent: self._send_intent_to_transport(completedIntent.nextIntent) else: fkey = completedIntent.targetAddr if fkey not in self._finalTransmitPending: fkey = self._addrManager.sendToAddress(completedIntent.targetAddr) if fkey not in self._finalTransmitPending: if isinstance(completedIntent.message, DeadEnvelope): fkey = completedIntent.message.deadAddress if fkey not in self._finalTransmitPending: fkey = self._addrManager.sendToAddress(fkey) if fkey in self._finalTransmitPending: if self._finalTransmitPending[fkey] != completedIntent: thesplog('Completed final intent %s does not match recorded final intent: %s', completedIntent.identify(), self._finalTransmitPending[fkey].identify(), level=logging.WARNING) del self._finalTransmitPending[fkey] else: thesplog('Completed Transmit Intent %s for unrecorded destination %s / %s in %s', completedIntent.identify(), str(self._addrManager.sendToAddress(completedIntent.targetAddr)), fkey, str(map(str,self._finalTransmitPending.keys())), level=logging.WARNING) self._sCBStats.inc('Action.Message Send.Unknown Completion') return
class systemCommonBase(object): def __init__(self, adminAddr, transport): self._adminAddr = adminAddr self.transport = transport self._addrManager = ActorAddressManager(adminAddr, self.transport.myAddress) self.transport.setAddressManager(self._addrManager) self._finalTransmitPending = { } # key = target ActorAddress, value=None or the last pending Intent self._awaitingAddressUpdate = { } # key = actorAddress waited on (usually local), value=array of transmit Intents self._receiveQueue = [] # array of ReceiveMessage to be processed self._children = [ ] # array of Addresses of children of this Actor/Admin self._governer = RateThrottle(RATE_THROTTLE) self._sCBStats = StatsManager() @property def address(self): return self.transport.myAddress @property def myAddress(self): return self.transport.myAddress @property def childAddresses(self): return self._children def _registerChild(self, childAddress): self._children.append(childAddress) def _handleChildExited(self, childAddress): self._sCBStats.inc('Common.Message Received.Child Actor Exited') self._addrManager.deadAddress(childAddress) self.transport.deadAddress(self._addrManager, childAddress) self._childExited(childAddress) self._children = [C for C in self._children if C != childAddress] if hasattr(self, '_exiting') and not self._children: # OK, all children are dead, can now exit this actor, but # make sure this final cleanup only occurs once # (e.g. transport.deadAddress above could recurse through # here as well. if not hasattr(self, '_exitedAlready'): self._exitedAlready = True self._sayGoodbye() self.transport.abort_run(drain=True) return True def _updateStatusResponse(self, resp): "Called to update a Thespian_SystemStatus or Thespian_ActorStatus with common information" for each in self.childAddresses: resp.addChild(each) for each in self._receiveQueue: resp.addReceivedMessage(each.sender, self.myAddress, each.message) self._sCBStats.copyToStatusResponse(resp) # Need to show _finalTransmitPending? where is head of chain? shown by transport? (no) resp.governer = str(self._governer) for addr in self._awaitingAddressUpdate: resp.addTXPendingAddressCount( addr, len(self._awaitingAddressUpdate[addr])) self.transport._updateStatusResponse(resp) def setLoggingControls(self, envelope): from thespian.system.utilis import thesplog_control msg = envelope.message thesplog_control(msg.threshold, msg.useLogging, msg.useFile) return True # ---------------------------------------------------------------------- # Transmit management def _send_intent(self, intent): self._governer.eventRatePause() # Check if there are any existing transmits in progress to # this address (on either the input address or the validated # address); if so, just add the new one to the list and # return. sendAddr = self._addrManager.sendToAddress(intent.targetAddr) finalIntent = self._finalTransmitPending.get( intent.targetAddr, self._finalTransmitPending.get(sendAddr, None)) self._finalTransmitPending[sendAddr or intent.targetAddr] = intent if finalIntent: finalIntent.nextIntent = intent self._sCBStats.inc('Actor.Message Send.Added to End of Sends') return self._send_intent_to_transport(intent) def _retryPendingChildOperations(self, childInstance, actualAddress): # actualAddress will be none if the child could not be created lcladdr = self._addrManager.getLocalAddress(childInstance) if not actualAddress: self._receiveQueue.append( ReceiveEnvelope(lcladdr, ChildActorExited(lcladdr))) if lcladdr in self._finalTransmitPending: # KWQ: what to do when actualAddress is None? self._finalTransmitPending[ actualAddress] = self._finalTransmitPending[lcladdr] del self._finalTransmitPending[lcladdr] if lcladdr in self._awaitingAddressUpdate: pending = self._awaitingAddressUpdate[lcladdr] del self._awaitingAddressUpdate[lcladdr] for each in pending: if actualAddress: # KWQ: confirm the following two lines can be removed; send_intent_to_transport should do this translation on its own. At that point, the changeTargetAddr method should be able to be removed. # if each.targetAddr == lcladdr: # each.changeTargetAddr(actualAddress) self._sCBStats.inc( 'Actor.Message Send.Transmit ReInitiated') self._send_intent(each) else: if not isinstance(each.message, PoisonMessage): self._receiveQueue.append( ReceiveEnvelope(self.myAddress, PoisonMessage(each.message))) self._sCBStats.inc( 'Actor.Message Send.Poison Return on Child Abort') each.result = SendStatus.Failed each.completionCallback() def _send_intent_to_transport(self, intent): thesplog('Attempting intent %s', intent.identify(), level=logging.DEBUG) if not hasattr(intent, '_addedCheckNextTransmitCB'): intent.addCallback(self._checkNextTransmit, self._checkNextTransmit) # Protection against duplicate callback additions in case # of a retry due to the CannotPickleAddress exception below. intent._addedCheckNextTransmitCB = True try: self.transport.scheduleTransmit(self._addrManager, intent) self._sCBStats.inc('Actor.Message Send.Transmit Started') except CannotPickleAddress as ex: thesplog('CannotPickleAddress, appending intent for %s (hash=%s)', ex.address, hash(ex.address), level=logging.DEBUG) self._awaitingAddressUpdate.setdefault(ex.address, []).append(intent) self._sCBStats.inc('Actor.Message Send.Postponed for Address') self._checkNextTransmit(0, intent) except Exception: import traceback thesplog('Declaring transmit of %s as Poison: %s', intent.identify(), traceback.format_exc(), exc_info=True, level=logging.ERROR) if not isinstance(intent.message, PoisonMessage): self._receiveQueue.append( ReceiveEnvelope(intent.targetAddr, PoisonMessage(intent.message))) self._sCBStats.inc('Actor.Message Send.Transmit Poison Rejection') intent.result = SendStatus.Failed intent.completionCallback() def _checkNextTransmit(self, result, completedIntent): # This is the callback for (all) TransmitIntents that will # send the next queued intent for that destination. if completedIntent.nextIntent: self._send_intent_to_transport(completedIntent.nextIntent) else: fkey = completedIntent.targetAddr if fkey not in self._finalTransmitPending: fkey = self._addrManager.sendToAddress( completedIntent.targetAddr) if fkey not in self._finalTransmitPending: if isinstance(completedIntent.message, DeadEnvelope): fkey = completedIntent.message.deadAddress if fkey not in self._finalTransmitPending: fkey = self._addrManager.sendToAddress(fkey) if fkey in self._finalTransmitPending: if self._finalTransmitPending[fkey] != completedIntent: thesplog( 'Completed final intent %s does not match recorded final intent: %s', completedIntent.identify(), self._finalTransmitPending[fkey].identify(), level=logging.WARNING) del self._finalTransmitPending[fkey] else: thesplog( 'Completed Transmit Intent %s for unrecorded destination %s / %s in %s', completedIntent.identify(), str( self._addrManager.sendToAddress( completedIntent.targetAddr)), fkey, str(map(str, self._finalTransmitPending.keys())), level=logging.WARNING) self._sCBStats.inc('Action.Message Send.Unknown Completion') return
class TestAddressManagerAddressRevocation(unittest.TestCase): scope='unit' def setUp(self): self.myAddress = 'me' self.am = ActorAddressManager(None, self.myAddress) def _makeLocalAndAssociated(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(lclAddr)) self.am.associateUseableAddress(self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) return lclAddr, mainAddr def testLocalAddressRevocation(self): lcladdr = self.am.createLocalAddress() self.am.deadAddress(lcladdr) self.assertIsNone(self.am.sendToAddress(lcladdr)) self.assertTrue(self.am.isDeadAddress(lcladdr)) self.assertEqual(lcladdr, self.am.getLocalAddress(lcladdr.addressDetails.addressInstanceNum)) def testMainAddressRevocation(self): addr = ActorAddress(id(self)) self.am.deadAddress(addr) self.assertEqual(addr, self.am.sendToAddress(addr)) self.assertTrue(self.am.isDeadAddress(addr)) def testLocalAddressRevocationAssociation(self): lclAddr, mainAddr = self._makeLocalAndAssociated() self.am.deadAddress(lclAddr) self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr)) self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr)) self.assertTrue(self.am.isDeadAddress(lclAddr)) self.assertTrue(self.am.isDeadAddress(mainAddr)) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr))) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr))) def testNonLocalAddressRevocationAssociation(self): lclAddr, mainAddr = self._makeLocalAndAssociated() self.am.deadAddress(mainAddr) self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr)) self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr)) self.assertTrue(self.am.isDeadAddress(lclAddr)) self.assertTrue(self.am.isDeadAddress(mainAddr)) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr))) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr))) def testAssociatedAddressRevocationIsUnique(self): lclAddr1, mainAddr1 = self._makeLocalAndAssociated() lclAddr2, mainAddr2 = self._makeLocalAndAssociated() lclAddr3, mainAddr3 = self._makeLocalAndAssociated() self.assertFalse(self.am.isDeadAddress(lclAddr1)) self.assertFalse(self.am.isDeadAddress(mainAddr1)) self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(mainAddr1))) self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(lclAddr1))) self.assertFalse(self.am.isDeadAddress(lclAddr2)) self.assertFalse(self.am.isDeadAddress(mainAddr2)) self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(mainAddr2))) self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(lclAddr2))) self.assertFalse(self.am.isDeadAddress(lclAddr3)) self.assertFalse(self.am.isDeadAddress(mainAddr3)) self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(mainAddr3))) self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(lclAddr3))) self.am.deadAddress(lclAddr1) self.am.deadAddress(mainAddr2) self.assertTrue(self.am.isDeadAddress(lclAddr1)) self.assertTrue(self.am.isDeadAddress(mainAddr1)) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr1))) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr1))) self.assertTrue(self.am.isDeadAddress(lclAddr2)) self.assertTrue(self.am.isDeadAddress(mainAddr2)) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr2))) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr2))) self.assertFalse(self.am.isDeadAddress(lclAddr3)) self.assertFalse(self.am.isDeadAddress(mainAddr3)) self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(mainAddr3))) self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(lclAddr3)))
def testCreate(self): am = ActorAddressManager(None, 'me') # no exception thrown assert True
class TestAddressManagerLocalAddressAssociations(unittest.TestCase): scope = 'unit' def setUp(self): self.myAddress = 'me' self.am = ActorAddressManager(None, self.myAddress) def testMakeAssociation(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(self)) self.am.associateUseableAddress( self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) # No exception thrown self.assertTrue(True) def _makeLocalAndAssociated(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(lclAddr)) self.am.associateUseableAddress( self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) return lclAddr, mainAddr def testAssociationRemembered(self): lclAddr, mainAddr = self._makeLocalAndAssociated() self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr)) self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr)) def testAssociationUnique(self): self.testAssociationRemembered() lclAddr2 = self.am.createLocalAddress() self.assertIsNone(self.am.sendToAddress(lclAddr2)) def testAssociationNotRequiredForUseableNonLocal(self): addr = ActorAddress(id(self)) self.assertEqual(addr, self.am.sendToAddress(addr)) def testAssociationEquality(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(self)) self.assertNotEqual(lclAddr, mainAddr) self.assertNotEqual(mainAddr, lclAddr) self.am.associateUseableAddress( self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) self.assertEqual(lclAddr, mainAddr) self.assertEqual(mainAddr, lclAddr) def testAssociationEqualityWithReconstitutedNonLocalAddress(self): lclAddr = self.am.createLocalAddress() mainAddr1 = ActorAddress(None) mainAddr2 = ActorAddress(9) self.assertNotEqual(mainAddr1, mainAddr2) self.am.associateUseableAddress( self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr1) self.assertEqual(lclAddr, mainAddr1) self.assertEqual(mainAddr1, lclAddr) self.assertNotEqual(lclAddr, mainAddr2) self.assertNotEqual(mainAddr2, lclAddr) mainAddr1_dup = ActorAddress(None) self.assertEqual(mainAddr1, mainAddr1_dup) self.assertNotEqual(mainAddr1_dup, lclAddr) self.assertEqual(lclAddr, mainAddr1_dup) self.am.importAddr(mainAddr1_dup) self.assertEqual(mainAddr1_dup, lclAddr) self.assertEqual(lclAddr, mainAddr1_dup) self.assertEqual(mainAddr1_dup, mainAddr1) def testAssociatedAddressesDoNotMatchArbitraryStuff(self): lclAddr1, mainAddr1 = self._makeLocalAndAssociated() self.assertNotEqual(None, lclAddr1) self.assertNotEqual(id(self), lclAddr1) self.assertNotEqual(0, lclAddr1) self.assertNotEqual("hi", lclAddr1) self.assertNotEqual(unittest.TestCase, lclAddr1) self.assertNotEqual(None, mainAddr1) self.assertNotEqual(id(self), mainAddr1) self.assertNotEqual(0, mainAddr1) self.assertNotEqual("hi", mainAddr1) self.assertNotEqual(unittest.TestCase, mainAddr1) self.assertNotEqual(lclAddr1, None) self.assertNotEqual(lclAddr1, id(self)) self.assertNotEqual(lclAddr1, 0) self.assertNotEqual(lclAddr1, "hi") self.assertNotEqual(lclAddr1, unittest.TestCase) self.assertNotEqual(mainAddr1, None) self.assertNotEqual(mainAddr1, id(self)) self.assertNotEqual(mainAddr1, 0) self.assertNotEqual(mainAddr1, "hi") self.assertNotEqual(mainAddr1, unittest.TestCase) def testAssociatedAddressEqualityIsUnique(self): lclAddr1, mainAddr1 = self._makeLocalAndAssociated() print('Set 1: %s --> %s' % (str(lclAddr1), str(mainAddr1))) lclAddr2, mainAddr2 = self._makeLocalAndAssociated() print('Set 2: %s --> %s' % (str(lclAddr2), str(mainAddr2))) lclAddr3, mainAddr3 = self._makeLocalAndAssociated() print('Set 3: %s --> %s' % (str(lclAddr3), str(mainAddr3))) self.assertEqual(lclAddr1, lclAddr1) self.assertEqual(lclAddr2, lclAddr2) self.assertEqual(lclAddr3, lclAddr3) self.assertEqual(mainAddr1, mainAddr1) self.assertEqual(mainAddr2, mainAddr2) self.assertEqual(mainAddr3, mainAddr3) self.assertEqual(lclAddr1, mainAddr1) self.assertEqual(lclAddr2, mainAddr2) self.assertEqual(lclAddr3, mainAddr3) self.assertEqual(mainAddr1, lclAddr1) self.assertEqual(mainAddr2, lclAddr2) self.assertEqual(mainAddr3, lclAddr3) self.assertNotEqual(lclAddr1, lclAddr2) self.assertNotEqual(lclAddr2, lclAddr1) self.assertNotEqual(lclAddr3, lclAddr2) self.assertNotEqual(lclAddr2, lclAddr3) self.assertNotEqual(lclAddr3, lclAddr1) self.assertNotEqual(lclAddr1, lclAddr3) self.assertNotEqual(mainAddr1, mainAddr2) self.assertNotEqual(mainAddr2, mainAddr1) self.assertNotEqual(mainAddr3, mainAddr2) self.assertNotEqual(mainAddr2, mainAddr3) self.assertNotEqual(mainAddr3, mainAddr1) self.assertNotEqual(mainAddr1, mainAddr3) self.assertNotEqual(mainAddr1, lclAddr2) self.assertNotEqual(mainAddr2, lclAddr1) self.assertNotEqual(mainAddr3, lclAddr2) self.assertNotEqual(mainAddr2, lclAddr3) self.assertNotEqual(mainAddr3, lclAddr1) self.assertNotEqual(mainAddr1, lclAddr3) self.assertNotEqual(lclAddr1, mainAddr2) self.assertNotEqual(lclAddr2, mainAddr1) self.assertNotEqual(lclAddr3, mainAddr2) self.assertNotEqual(lclAddr2, mainAddr3) self.assertNotEqual(lclAddr3, mainAddr1) self.assertNotEqual(lclAddr1, mainAddr3)
class systemCommonBase(object): def __init__(self, adminAddr, transport): self._adminAddr = adminAddr self.transport = transport self._addrManager = ActorAddressManager(adminAddr, self.transport.myAddress) self.transport.setAddressManager(self._addrManager) self._pendingTransmits = PendingTransmits(self._addrManager) self._awaitingAddressUpdate = AddressWaitTransmits() self._receiveQueue = [] # array of ReceiveMessage to be processed self._children = [ ] # array of Addresses of children of this Actor/Admin self._governer = RateThrottle(RATE_THROTTLE) self._sCBStats = StatsManager() @property def address(self): return self.transport.myAddress @property def myAddress(self): return self.transport.myAddress @property def childAddresses(self): return self._children def _registerChild(self, childAddress): self._children.append(childAddress) def _handleChildExited(self, childAddress): self._sCBStats.inc('Common.Message Received.Child Actor Exited') self.transport.deadAddress(self._addrManager, childAddress) self._childExited(childAddress) self._children = [C for C in self._children if C != childAddress] if hasattr(self, '_exiting') and not self._children: # OK, all children are dead, can now exit this actor, but # make sure this final cleanup only occurs once # (e.g. transport.deadAddress above could recurse through # here as well. if not hasattr(self, '_exitedAlready'): self._exitedAlready = True self._sayGoodbye() self.transport.abort_run(drain=True) return False return True def _updateStatusResponse(self, resp): "Called to update a Thespian_SystemStatus or Thespian_ActorStatus with common information" for each in self.childAddresses: resp.addChild(each) for each in self._receiveQueue: resp.addReceivedMessage(each.sender, self.myAddress, each.message) self._sCBStats.copyToStatusResponse(resp) self._pendingTransmits.update_status_response(resp, self.myAddress) resp.governer = str(self._governer) fmap(lambda x: resp.addTXPendingAddressCount(*len_second(x)), self._awaitingAddressUpdate) self.transport._updateStatusResponse(resp) def setLoggingControls(self, envelope): from thespian.system.utilis import thesplog_control msg = envelope.message thesplog_control(msg.threshold, msg.useLogging, msg.useFile) return True # ---------------------------------------------------------------------- # Transmit management def _send_intent(self, intent, curtime=None): self._governer.eventRatePause(curtime or datetime.now()) # Check if there are any existing transmits in progress to # this address (on either the input address or the validated # address); if so, just add the new one to the list and # return. if self._pendingTransmits.p_can_send_now(self._sCBStats, intent): self._send_intent_to_transport(intent) def _retryPendingChildOperations(self, childInstance, actualAddress): # actualAddress will be none if the child could not be created lcladdr = self._addrManager.getLocalAddress(childInstance) if not actualAddress: self._receiveQueue.append( ReceiveEnvelope(lcladdr, ChildActorExited(lcladdr))) else: self._pendingTransmits.change_address_for_transmit( lcladdr, actualAddress) for each in self._awaitingAddressUpdate\ .remove_intents_for_address(lcladdr): if actualAddress: self._sCBStats.inc('Actor.Message Send.Transmit ReInitiated') self._send_intent(each) else: if not isinstance(each.message, PoisonMessage): self._receiveQueue.append( ReceiveEnvelope( self.myAddress, PoisonMessage(each.message, 'Child Aborted'))) self._sCBStats.inc( 'Actor.Message Send.Poison Return on Child Abort') each.tx_done(SendStatus.Failed) def _send_intent_to_transport(self, intent): thesplog('Attempting intent %s', intent.identify(), level=logging.DEBUG) if not hasattr(intent, '_addedCheckNextTransmitCB'): intent.addCallback(self._checkNextTransmit, self._checkNextTransmit) # Protection against duplicate callback additions in case # of a retry due to the CannotPickleAddress exception below. intent._addedCheckNextTransmitCB = True intent._transmit_pending_to_transport = True try: self.transport.scheduleTransmit(self._addrManager, intent) self._sCBStats.inc('Actor.Message Send.Transmit Started') return except CannotPickleAddress as ex: thesplog('CannotPickleAddress, appending intent for %s', ex.address, level=logging.DEBUG) self._sCBStats.inc('Actor.Message Send.Postponed for Address') self._awaitingAddressUpdate.add(ex.address, intent) # Callback is still registered, so callback can use the # _transmit_pending_to_transport to determine if it was # actually being transmitted or not. intent._transmit_pending_to_transport = False next_intent = self._pendingTransmits.cannot_send_now(intent) if next_intent: self._send_intent_to_transport(next_intent) except Exception: import traceback thesplog('Declaring transmit of %s as Poison: %s', intent.identify(), traceback.format_exc(), exc_info=True, level=logging.ERROR) if not isinstance(intent.message, PoisonMessage): self._receiveQueue.append( ReceiveEnvelope( intent.targetAddr, PoisonMessage(intent.message, traceback.format_exc()))) self._sCBStats.inc('Actor.Message Send.Transmit Poison Rejection') intent.tx_done(SendStatus.Failed) def _checkNextTransmit(self, result, completedIntent): # This is the callback for (all) TransmitIntents that will # send the next queued intent for that destination. if getattr(completedIntent, '_transmit_pending_to_transport', False): next_intent = self._pendingTransmits.get_next(completedIntent) if next_intent: self._send_intent_to_transport(next_intent) def drainTransmits(self): drainLimit = ExpirationTimer(MAX_SHUTDOWN_DRAIN_PERIOD) for drain_remaining_time in unexpired(drainLimit): if not self.transport.run(TransmitOnly, drain_remaining_time.remaining()): break # no transmits left
class TestAddressManagerAddressRevocation(unittest.TestCase): scope = 'unit' def setUp(self): self.myAddress = 'me' self.am = ActorAddressManager(None, self.myAddress) def _makeLocalAndAssociated(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(lclAddr)) self.am.associateUseableAddress( self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) return lclAddr, mainAddr def testLocalAddressRevocation(self): lcladdr = self.am.createLocalAddress() self.am.deadAddress(lcladdr) self.assertIsNone(self.am.sendToAddress(lcladdr)) self.assertTrue(self.am.isDeadAddress(lcladdr)) self.assertEqual( lcladdr, self.am.getLocalAddress(lcladdr.addressDetails.addressInstanceNum)) def testMainAddressRevocation(self): addr = ActorAddress(id(self)) self.am.deadAddress(addr) self.assertEqual(addr, self.am.sendToAddress(addr)) self.assertTrue(self.am.isDeadAddress(addr)) def testLocalAddressRevocationAssociation(self): lclAddr, mainAddr = self._makeLocalAndAssociated() self.am.deadAddress(lclAddr) self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr)) self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr)) self.assertTrue(self.am.isDeadAddress(lclAddr)) self.assertTrue(self.am.isDeadAddress(mainAddr)) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr))) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr))) def testNonLocalAddressRevocationAssociation(self): lclAddr, mainAddr = self._makeLocalAndAssociated() self.am.deadAddress(mainAddr) self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr)) self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr)) self.assertTrue(self.am.isDeadAddress(lclAddr)) self.assertTrue(self.am.isDeadAddress(mainAddr)) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr))) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr))) def testAssociatedAddressRevocationIsUnique(self): lclAddr1, mainAddr1 = self._makeLocalAndAssociated() lclAddr2, mainAddr2 = self._makeLocalAndAssociated() lclAddr3, mainAddr3 = self._makeLocalAndAssociated() self.assertFalse(self.am.isDeadAddress(lclAddr1)) self.assertFalse(self.am.isDeadAddress(mainAddr1)) self.assertFalse( self.am.isDeadAddress(self.am.sendToAddress(mainAddr1))) self.assertFalse(self.am.isDeadAddress( self.am.sendToAddress(lclAddr1))) self.assertFalse(self.am.isDeadAddress(lclAddr2)) self.assertFalse(self.am.isDeadAddress(mainAddr2)) self.assertFalse( self.am.isDeadAddress(self.am.sendToAddress(mainAddr2))) self.assertFalse(self.am.isDeadAddress( self.am.sendToAddress(lclAddr2))) self.assertFalse(self.am.isDeadAddress(lclAddr3)) self.assertFalse(self.am.isDeadAddress(mainAddr3)) self.assertFalse( self.am.isDeadAddress(self.am.sendToAddress(mainAddr3))) self.assertFalse(self.am.isDeadAddress( self.am.sendToAddress(lclAddr3))) self.am.deadAddress(lclAddr1) self.am.deadAddress(mainAddr2) self.assertTrue(self.am.isDeadAddress(lclAddr1)) self.assertTrue(self.am.isDeadAddress(mainAddr1)) self.assertTrue(self.am.isDeadAddress( self.am.sendToAddress(mainAddr1))) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr1))) self.assertTrue(self.am.isDeadAddress(lclAddr2)) self.assertTrue(self.am.isDeadAddress(mainAddr2)) self.assertTrue(self.am.isDeadAddress( self.am.sendToAddress(mainAddr2))) self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr2))) self.assertFalse(self.am.isDeadAddress(lclAddr3)) self.assertFalse(self.am.isDeadAddress(mainAddr3)) self.assertFalse( self.am.isDeadAddress(self.am.sendToAddress(mainAddr3))) self.assertFalse(self.am.isDeadAddress( self.am.sendToAddress(lclAddr3)))