def core_common_transmit(self, transmit_intent, from_addr): try: if self.isMyAddress(transmit_intent.targetAddr): if transmit_intent.message: self._myInputQ.put( (from_addr, transmit_intent.serMsg), True, timePeriodSeconds(transmit_intent.delay())) else: tgtQ = self._queues.find(transmit_intent.targetAddr) if tgtQ: tgtQ.put((from_addr, transmit_intent.serMsg), True, timePeriodSeconds(transmit_intent.delay())) else: # None means sent by parent, so don't send BACK to parent if unknown topOrFromBelow = from_addr if self._parentQ else None (self._parentQ or self._adminQ).put( (topOrFromBelow, transmit_intent.serMsg), True, timePeriodSeconds(transmit_intent.delay())) transmit_intent.tx_done(SendStatus.Sent) return except Q.Full: pass transmit_intent.tx_done(SendStatus.DeadTarget if not isinstance( transmit_intent._message, (ChildActorExited, ActorExitRequest)) else SendStatus.Failed)
def _scheduleTransmitActual(self, transmitIntent): try: if transmitIntent.targetAddr == self.myAddress: if transmitIntent.message: self._myInputQ.put( (self._myQAddress, transmitIntent.serMsg), True, timePeriodSeconds(transmitIntent.delay())) else: tgtQ = self._queues.find(transmitIntent.targetAddr) if tgtQ: tgtQ.put((self._myQAddress, transmitIntent.serMsg), True, timePeriodSeconds(transmitIntent.delay())) else: # None means sent by parent, so don't send BACK to parent if unknown topOrFromBelow = self._myQAddress if self._parentQ else None (self._parentQ or self._adminQ).put( (topOrFromBelow, transmitIntent.serMsg), True, timePeriodSeconds(transmitIntent.delay())) transmitIntent.tx_done(SendStatus.Sent) return except Q.Full: pass transmitIntent.tx_done(SendStatus.DeadTarget if not isinstance( transmitIntent._message, (ChildActorExited, ActorExitRequest)) else SendStatus.Failed) thesplog('Q.Full %s to %s result %s', transmitIntent._message, transmitIntent.targetAddr, transmitIntent.result)
def core_common_transmit(self, transmit_intent, from_addr): try: if self.isMyAddress(transmit_intent.targetAddr): if transmit_intent.message: self._myInputQ.put( (from_addr, transmit_intent.serMsg), True, timePeriodSeconds(transmit_intent.delay())) else: tgtQ = self._queues.find(transmit_intent.targetAddr) if tgtQ: tgtQ.put((from_addr, transmit_intent.serMsg), True, timePeriodSeconds(transmit_intent.delay())) else: # None means sent by parent, so don't send BACK to parent if unknown topOrFromBelow = from_addr if self._parentQ else None (self._parentQ or self._adminQ).put( (topOrFromBelow, transmit_intent.serMsg), True, timePeriodSeconds(transmit_intent.delay())) transmit_intent.tx_done(SendStatus.Sent) return except Q.Full: pass transmit_intent.tx_done( SendStatus.DeadTarget if not isinstance(transmit_intent._message, ( ChildActorExited, ActorExitRequest)) else SendStatus.Failed)
def _runSends(self, timeout=None, stop_on_available=False): numsends = 0 endtime = ((datetime.now() + toTimeDeltaOrNone(timeout)) if timeout else None) while not endtime or datetime.now() < endtime: while self._pendingSends: numsends += 1 if self.procLimit and numsends > self.procLimit: raise RuntimeError('Too many sends') self._realizeWakeups() self._runSingleSend(self._pendingSends.pop(0)) if stop_on_available and \ any([not isInternalActorSystemMessage(M) for M in getattr(stop_on_available.instance, 'responses', [])]): return if not endtime: return now = datetime.now() valid_wakeups = [(W - now) for W in self._wakeUps if W <= endtime] if not valid_wakeups: return import time time.sleep(max(0, timePeriodSeconds(min(valid_wakeups)))) self._realizeWakeups()
def _runSends(self, timeout=None, stop_on_available=False): numsends = 0 endtime = ExpirationTimer(toTimeDeltaOrNone(timeout)) while not endtime.expired(): while self._pendingSends: numsends += 1 if self.procLimit and numsends > self.procLimit: raise RuntimeError('Too many sends') self._realizeWakeups() with self._private_lock: try: nextmsg = self._pendingSends.pop(0) except IndexError: pass else: self._runSingleSend(nextmsg) if stop_on_available and \ any([not isInternalActorSystemMessage(M) for M in getattr(stop_on_available.instance, 'responses', [])]): return if endtime.remaining(forever=-1) == -1: return next_wakeup = self._next_wakeup() if next_wakeup is None or next_wakeup > endtime: return time.sleep(max(0, timePeriodSeconds(next_wakeup.remaining()))) self._realizeWakeups()
def _runSends(self, timeout=None, stop_on_available=False): numsends = 0 endtime = ExpirationTimer(toTimeDeltaOrNone(timeout)) for endt in unexpired(endtime): while self._pendingSends: numsends += 1 if self.procLimit and numsends > self.procLimit: raise RuntimeError('Too many sends') self._realizeWakeups() with self._private_lock: try: nextmsg = self._pendingSends.pop(0) except IndexError: pass else: self._runSingleSend(nextmsg) if stop_on_available and \ any([not isInternalActorSystemMessage(M) for M in getattr(stop_on_available.instance, 'responses', [])]): return if endt.remaining(forever=-1) == -1: return next_wakeup = self._next_wakeup() if next_wakeup is None or next_wakeup > endt: return time.sleep( max(0, timePeriodSeconds(next_wakeup.view().remaining()))) self._realizeWakeups()
def testOverMax__expected_duration_is_21_seconds(self): # The rate limiter allows bursts.. the bigger cnt is the # closer to the actual limit the result will be, but the # longer the test will take. cnt = 300 tt = send_at_rate(10, 100, cnt) print('send_at_rate(10, 100, %s) --> %s' % (cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 15 > actRate # add a little buffer for overage... just a little
def testOverMax__expected_duration_is_21_seconds(self): # The rate limiter allows bursts.. the bigger cnt is the # closer to the actual limit the result will be, but the # longer the test will take. cnt = 300 tt = send_at_rate(10, 100, cnt) print('send_at_rate(10, 100, %s) --> %s'%(cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 15 > actRate # add a little buffer for overage... just a little
def eventRatePause(self): """This is the main method that should be called each time an event is to occur. It will block internally until it is time for the next event to occur. """ if not hasattr(self, '_curRate'): self._runningCount += 1 # runningCount is the total # since the last time it was # zeroed, so it's not just wthin the last second, but it does # provide a threshold above which the actual rate should be # observed and possibly throttled. This will begin to take an # interest in the actual rate when the runningCount reaches an # arbitrary 70% of the maximum rate. if self._runningCount < (self._maxRate * 0.70): return self._curRate = 0 self._timeMark = datetime.now() self._goodMarks = 0 return self._curRate += 1 newT = datetime.now() deltaT = newT - self._timeMark if deltaT < timedelta(seconds=1): return rate = self._curRate / timePeriodSeconds(deltaT) if rate > self._maxRate: # Slow down a little delay(0.1) self._goodMarks = 0 return self._goodMarks += 1 if self._goodMarks > self._maxRate: delattr(self, '_curRate') self._runningCount = 0 return
def eventRatePause(self): """This is the main method that should be called each time an event is to occur. It will block internally until it is time for the next event to occur. """ if not hasattr(self, '_curRate'): self._runningCount += 1 # runningCount is the total # since the last time it was # zeroed, so it's not just wthin the last second, but it does # provide a threshold above which the actual rate should be # observed and possibly throttled. This will begin to take an # interest in the actual rate when the runningCount reaches an # arbitrary 70% of the maximum rate. if self._runningCount < (self._maxRate * 0.70): return self._curRate = 0 self._timeMark = Timer() self._goodMarks = 0 return self._curRate += 1 deltaT = self._timeMark.elapsed() if deltaT < timedelta(seconds=1): return rate = self._curRate / timePeriodSeconds(deltaT) if rate > self._maxRate: # Slow down a little delay(0.1) self._goodMarks = 0 return self._goodMarks += 1 if self._goodMarks > self._maxRate: delattr(self, '_curRate') self._runningCount = 0 return
def core_common_receive(self, incoming_handler, for_local_addr, run_time_f): """Core scheduling method; called by the current Actor process when idle to await new messages (or to do background processing). """ if incoming_handler == TransmitOnly or \ isinstance(incoming_handler, TransmitOnly): # transmits are not queued/multistage in this transport, no waiting return 0 self._aborting_run = False while not run_time_f().expired() and not self._aborting_run: try: # Unfortunately, the Queue object is not signal-safe, # so a frequent wakeup is needed to check # _checkChildren and _shutdownSignalled. rcvd = self._myInputQ.get(True, min(run_time_f().remainingSeconds() or QUEUE_CHECK_PERIOD, QUEUE_CHECK_PERIOD)) except Q.Empty: if not self._checkChildren and not self._shutdownSignalled: # Probably a timeout, but let the while loop decide for sure continue rcvd = 'BuMP' if rcvd == 'BuMP': relayAddr = sendAddr = destAddr = for_local_addr if self._checkChildren: self._checkChildren = False msg = ChildMayHaveDied() elif self._shutdownSignalled: self._shutdownSignalled = False msg = ActorExitRequest() else: return Thespian__UpdateWork() else: relayAddr, (sendAddr, destAddr, msg) = rcvd if not self._queues.find(sendAddr): # We don't directly know about this sender, so # remember what path this arrived on to know where to # direct future messages for this sender. if relayAddr and self._queues.find(relayAddr) and \ not self._fwdvia.find(sendAddr): # relayAddr might be None if it's our parent, which is OK because # the default message forwarding is to the parent. If it's not # none, it should be in self._queues though! self._fwdvia.add(sendAddr, relayAddr) if hasattr(self, '_addressMgr'): destAddr,msg = self._addressMgr.prepMessageSend(destAddr, msg) if destAddr is None: thesplog('Unexpected target inaccessibility for %s', msg, level = logging.WARNING) raise CannotPickleAddress(destAddr) if msg is SendStatus.DeadTarget: thesplog('Faking message "sent" because target is dead and recursion avoided.') continue if self.isMyAddress(destAddr): if incoming_handler is None: return ReceiveEnvelope(sendAddr, msg) r = incoming_handler(ReceiveEnvelope(sendAddr, msg)) if not r: return r # handler returned False, indicating run() should exit else: # Note: the following code has implicit knowledge of serialize() and xmit putQValue = lambda relayer: (relayer, (sendAddr, destAddr, msg)) deadQValue = lambda relayer: (relayer, (sendAddr, self._adminAddr, DeadEnvelope(destAddr, msg))) # Must forward this packet via a known forwarder or our parent. send_dead = False tgtQ = self._queues.find(destAddr) if tgtQ: sendArgs = putQValue(for_local_addr), True if not tgtQ: tgtA = self._fwdvia.find(destAddr) if tgtA: tgtQ = self._queues.find(tgtA) sendArgs = putQValue(None), else: for each in self._deadaddrs: if destAddr == each: send_dead = True if tgtQ: try: tgtQ.put(*sendArgs, timeout=timePeriodSeconds(MAX_QUEUE_TRANSMIT_PERIOD)) continue except Q.Full: thesplog('Unable to send msg %s to dest %s; dead lettering', msg, destAddr) send_dead = True if send_dead: try: (self._parentQ or self._adminQ).put( deadQValue(for_local_addr if self._parentQ else None), True, timePeriodSeconds(MAX_QUEUE_TRANSMIT_PERIOD)) except Q.Full: thesplog('Unable to send deadmsg %s to %s or admin; discarding', msg, destAddr) continue # Not sure how to route this message yet. It # could be a heretofore silent child of one of our # children, it could be our parent (whose address # we don't know), or it could be elsewhere in the # tree. # # Try sending it to the parent first. If the # parent can't determine the routing, it will be # sent back down (relayAddr will be None in that # case) and it must be sprayed out to all children # in case the target lives somewhere beneath us. # Note that _parentQ will be None for top-level # actors, which send up to the Admin instead. # # As a special case, the external system is the # parent of the admin, but the admin is the # penultimate parent of all others, so this code # must keep the admin and the parent from playing # ping-pong with the message. But... the message # might be directed to the external system, which # is the parent of the Admin, so we need to check # with it first. # parentQ == None but adminQ good --> external # parentQ and adminQ and myAddress == adminAddr --> Admin # parentQ and adminQ and myAddress != adminADdr --> other Actor if relayAddr: # Send message up to the parent to see if the # parent knows how to forward it try: (self._parentQ or self._adminQ).put( putQValue(for_local_addr if self._parentQ else None), True, timePeriodSeconds(MAX_QUEUE_TRANSMIT_PERIOD)) except Q.Full: thesplog('Unable to send dead msg %s to %s or admin; discarding', msg, destAddr) else: # Sent by parent or we are an external, so this # may be some grandchild not currently known. # Do the worst case and just send this message # to ALL immediate children, hoping it will # get there via some path. for A,AQ in self._queues.items(): if A not in [self._adminAddr, str(self._adminAddr)]: # None means sent by Parent, so don't # send BACK to parent if unknown try: AQ.put(putQValue(None), True, timePeriodSeconds(MAX_QUEUE_TRANSMIT_PERIOD)) except Q.Full: pass return None
def testSlow__expected_duration_is_20_seconds(self): cnt = 10 tt = send_at_rate(10, 0.5, cnt) print('send_at_rate(10, 0.5, %s) --> %s'%(cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 10 > actRate
def unstable_test(asys, *unstable_bases): if asys.base_name in unstable_bases and \ not pytest.config.getoption('unstable', default=False): pytest.skip("Test unstable for %s system base"%asys.base_name) def actor_system_unsupported(asys, *unsupported_bases): if asys.base_name in unsupported_bases: pytest.skip("Functionality not supported for %s system base"%asys.base_name) from thespian.system.timing import timePeriodSeconds import time inTestDelay = lambda period: time.sleep(timePeriodSeconds(period)) def delay_for_next_of_kin_notification(system): if system.base_name == 'multiprocQueueBase': # The multiprocQueueBase signal processor cannot interrupt a # sleeping Queue.get(), so for this base it is necessary to # wait for the timeout on the Queue.get() to allow it time to # notice and process the child exit. time.sleep(2.5) elif system.base_name == 'multiprocUDPBase': time.sleep(0.6) else: time.sleep(0.1)
def testNearMax__expected_duration_is_11_seconds(self): cnt = 100 tt = send_at_rate(10, 9, cnt) print('send_at_rate(10, 9, %s) --> %s'%(cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 10 > actRate
assert 10 > actRate def testOverMax__expected_duration_is_21_seconds(self): # The rate limiter allows bursts.. the bigger cnt is the # closer to the actual limit the result will be, but the # longer the test will take. cnt = 300 tt = send_at_rate(10, 100, cnt) print('send_at_rate(10, 100, %s) --> %s' % (cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 15 > actRate # add a little buffer for overage... just a little def testSlow__expected_duration_is_20_seconds(self): cnt = 10 tt = send_at_rate(10, 0.5, cnt) print('send_at_rate(10, 0.5, %s) --> %s' % (cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 10 > actRate if __name__ == "__main__": for ar in [5, 9, 0.2, 100]: #cnt = 10 * ar # this way all return 10 s unless rate limited cnt = 1000 if ar > 10 else ( 50 if ar >= 1 else 5 ) # this way see time taken for const # of inputs tt = send_at_rate(10, ar, cnt) actRate = cnt / timePeriodSeconds(tt) print('send_at_rate(10, %s, %s) --> %s, rate=%s' % (str(ar), str(cnt), str(tt), actRate))
def testNearMax__expected_duration_is_11_seconds(self): cnt = 100 tt = send_at_rate(10, 9, cnt) print('send_at_rate(10, 9, %s) --> %s' % (cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 10 > actRate
print('send_at_rate(10, 9, %s) --> %s'%(cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 10 > actRate def testOverMax__expected_duration_is_21_seconds(self): # The rate limiter allows bursts.. the bigger cnt is the # closer to the actual limit the result will be, but the # longer the test will take. cnt = 300 tt = send_at_rate(10, 100, cnt) print('send_at_rate(10, 100, %s) --> %s'%(cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 15 > actRate # add a little buffer for overage... just a little def testSlow__expected_duration_is_20_seconds(self): cnt = 10 tt = send_at_rate(10, 0.5, cnt) print('send_at_rate(10, 0.5, %s) --> %s'%(cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 10 > actRate if __name__ == "__main__": for ar in [5, 9, 0.2, 100]: #cnt = 10 * ar # this way all return 10 s unless rate limited cnt = 1000 if ar > 10 else (50 if ar >= 1 else 5) # this way see time taken for const # of inputs tt = send_at_rate(10, ar, cnt) actRate = cnt / timePeriodSeconds(tt) print('send_at_rate(10, %s, %s) --> %s, rate=%s'%(str(ar), str(cnt), str(tt), actRate))
def update_elapsed_time(time_base, elapsed): with patch('thespian.system.timing.currentTime') as p_ctime: p_ctime.return_value = time_base + (timePeriodSeconds( elapsed) if isinstance(elapsed, timedelta) else elapsed) yield p_ctime.return_value
import pytest from pytest import raises from thespian.test import * import time from thespian.actors import * from datetime import timedelta from thespian.system.timing import timePeriodSeconds MAX_ASK_WAIT_PERIOD = timedelta(seconds=7) UPDATE_WAIT_PERIOD = timedelta(milliseconds=300) EXIT_WAIT_PERIOD = timedelta(milliseconds=500) update_wait = lambda: time.sleep(timePeriodSeconds(UPDATE_WAIT_PERIOD)) exit_wait = lambda: time.sleep(timePeriodSeconds(EXIT_WAIT_PERIOD)) colors = ['Red', 'Blue', 'Green', 'Yellow'] class SetCap(object): def __init__(self, capName, capValue): self.capName = capName self.capValue = capValue class ColorActorBase(Actor): """This actor has a particular color (identified by self.color), and requires that color to be a capability of the ActorSystem it runs in.
def unstable_test(asys, *unstable_bases): if asys.base_name in unstable_bases and \ not pytest.config.getoption('unstable', default=False): pytest.skip("Test unstable for %s system base" % asys.base_name) def actor_system_unsupported(asys, *unsupported_bases): if asys.base_name in unsupported_bases: pytest.skip("Functionality not supported for %s system base" % asys.base_name) from thespian.system.timing import timePeriodSeconds import time inTestDelay = lambda period: time.sleep(timePeriodSeconds(period)) def delay_for_next_of_kin_notification(system): if system.base_name == 'multiprocQueueBase': # The multiprocQueueBase signal processor cannot interrupt a # sleeping Queue.get(), so for this base it is necessary to # wait for the timeout on the Queue.get() to allow it time to # notice and process the child exit. time.sleep(2.5) elif system.base_name == 'multiprocUDPBase': time.sleep(0.6) else: time.sleep(0.1)
def testSlow__expected_duration_is_20_seconds(self): cnt = 10 tt = send_at_rate(10, 0.5, cnt) print('send_at_rate(10, 0.5, %s) --> %s' % (cnt, str(tt))) actRate = cnt / timePeriodSeconds(tt) assert 10 > actRate
def update_elapsed_time(time_base, elapsed): with patch('thespian.system.timing.currentTime') as p_ctime: p_ctime.return_value = time_base + (timePeriodSeconds(elapsed) if isinstance(elapsed, timedelta) else elapsed) yield p_ctime.return_value
def _runWithExpiry(self, incomingHandler): """Core scheduling method; called by the current Actor process when idle to await new messages (or to do background processing). """ if incomingHandler == TransmitOnly or \ isinstance(incomingHandler, TransmitOnly): # transmits are not queued/multistage in this transport, no waiting return 0 self._aborting_run = False while not self.run_time.expired() and not self._aborting_run: try: rcvd = self._myInputQ.get(True, self.run_time.remainingSeconds()) except Q.Empty: # Probably a timeout, but let the while loop decide for sure continue if rcvd == 'BuMP': return Thespian__UpdateWork() relayAddr, (sendAddr, destAddr, msg) = rcvd if not self._queues.find(sendAddr): # We don't directly know about this sender, so # remember what path this arrived on to know where to # direct future messages for this sender. if relayAddr and self._queues.find(relayAddr) and \ not self._fwdvia.find(sendAddr): # relayAddr might be None if it's our parent, which is OK because # the default message forwarding is to the parent. If it's not # none, it should be in self._queues though! self._fwdvia.add(sendAddr, relayAddr) if hasattr(self, '_addressMgr'): destAddr,msg = self._addressMgr.prepMessageSend(destAddr, msg) if destAddr is None: thesplog('Unexpected target inaccessibility for %s', msg, level = logging.WARNING) raise CannotPickleAddress(destAddr) if msg is SendStatus.DeadTarget: thesplog('Faking message "sent" because target is dead and recursion avoided.') continue if destAddr == self._myQAddress: if incomingHandler is None: return ReceiveEnvelope(sendAddr, msg) if not incomingHandler(ReceiveEnvelope(sendAddr, msg)): return # handler returned False, indicating run() should exit else: # Note: the following code has implicit knowledge of serialize() and xmit putQValue = lambda relayer: (relayer, (sendAddr, destAddr, msg)) deadQValue = lambda relayer: (relayer, (sendAddr, self._adminAddr, DeadEnvelope(destAddr, msg))) # Must forward this packet via a known forwarder or our parent. tgtQ = self._queues.find(destAddr) if tgtQ: sendArgs = putQValue(self.myAddress), True if not tgtQ: tgtA = self._fwdvia.find(destAddr) if tgtA: tgtQ = self._queues.find(tgtA) sendArgs = putQValue(None), if tgtQ: try: tgtQ.put(*sendArgs, timeout=timePeriodSeconds(MAX_QUEUE_TRANSMIT_PERIOD)) except Q.Full: thesplog('Unable to send msg %s to dest %s; dead lettering', msg, destAddr) try: (self._parentQ or self._adminQ).put( deadQValue(self.myAddress if self._parentQ else None), True, timePeriodSeconds(MAX_QUEUE_TRANSMIT_PERIOD)) except Q.Full: thesplog('Unable to send deadmsg %s to %s or admin; discarding', msg, destAddr) else: # Not sure how to route this message yet. It # could be a heretofore silent child of one of our # children, it could be our parent (whose address # we don't know), or it could be elsewhere in the # tree. # # Try sending it to the parent first. If the # parent can't determine the routing, it will be # sent back down (relayAddr will be None in that # case) and it must be sprayed out to all children # in case the target lives somewhere beneath us. # Note that _parentQ will be None for top-level # actors, which send up to the Admin instead. # # As a special case, the external system is the # parent of the admin, but the admin is the # penultimate parent of all others, so this code # must keep the admin and the parent from playing # ping-pong with the message. But... the message # might be directed to the external system, which # is the parent of the Admin, so we need to check # with it first. # parentQ == None but adminQ good --> external # parentQ and adminQ and myAddress == adminAddr --> Admin # parentQ and adminQ and myAddress != adminADdr --> other Actor if relayAddr: # Send message up to the parent to see if the # parent knows how to forward it try: (self._parentQ or self._adminQ).put( putQValue(self.myAddress if self._parentQ else None), True, timePeriodSeconds(MAX_QUEUE_TRANSMIT_PERIOD)) except Q.Full: thesplog('Unable to send dead msg %s to %s or admin; discarding', msg, destAddr) else: # Sent by parent or we are an external, so this # may be some grandchild not currently known. # Do the worst case and just send this message # to ALL immediate children, hoping it will # get there via some path. for A,AQ in self._queues.items(): if A not in [self._adminAddr, str(self._adminAddr)]: # None means sent by Parent, so don't # send BACK to parent if unknown try: AQ.put(putQValue(None), True, timePeriodSeconds(MAX_QUEUE_TRANSMIT_PERIOD)) except Q.Full: pass return None
systems (which should not be an issue under normal operations). """ import pytest from pytest import raises from thespian.test import * import time from thespian.actors import * from datetime import timedelta from thespian.system.timing import timePeriodSeconds MAX_ASK_WAIT_PERIOD = timedelta(seconds=7) UPDATE_WAIT_PERIOD = timedelta(milliseconds=300) EXIT_WAIT_PERIOD = timedelta(milliseconds=500) update_wait = lambda: time.sleep(timePeriodSeconds(UPDATE_WAIT_PERIOD)) exit_wait = lambda: time.sleep(timePeriodSeconds(EXIT_WAIT_PERIOD)) colors = ['Red', 'Blue', 'Green', 'Yellow'] class SetCap(object): def __init__(self, capName, capValue): self.capName = capName self.capValue = capValue class GetCaps(object): def __init__(self): self.caps = None self.reqs = None
def report(what, sysBase, elapsed, nMessages, nActors): print('%3d Actors, %29s %29s -- %s -- %5.2f/sec overall -- %7.2f msg/sec' % (nActors, what, sysBase, elapsed, nMessages / timePeriodSeconds(elapsed), nMessages * nActors / timePeriodSeconds(elapsed)))
def report(what, sysBase, elapsed, nMessages, nActors): print('%5d Actors, %30s %22s -- %s -- %5.2f/sec overall -- %7.2f msg/sec'%( nActors, what, sysBase, elapsed, nMessages / timePeriodSeconds(elapsed), nMessages * nActors / timePeriodSeconds(elapsed)))