1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19  from twisted.internet import reactor, defer 
 20  from twisted.python import log 
 21   
 23   
 24      _reactor = reactor 
 25   
 27          self._events = [] 
 28          self._flushObservers = [] 
 29          self._timer = None 
 30          self._in_turn = False 
  31   
 32 -    def append(self, cb, args, kwargs): 
  33          self._events.append((cb, args, kwargs)) 
 34          if not self._timer: 
 35              self._timer = self._reactor.callLater(0, self._turn) 
  36   
 38          self._timer = None 
 39          self._in_turn = True 
 40           
 41           
 42           
 43          events, self._events = self._events, [] 
 44          for cb, args, kwargs in events: 
 45              try: 
 46                  cb(*args, **kwargs) 
 47              except: 
 48                  log.err() 
 49          self._in_turn = False 
 50          if self._events and not self._timer: 
 51              self._timer = self._reactor.callLater(0, self._turn) 
 52          if not self._events: 
 53              observers, self._flushObservers = self._flushObservers, [] 
 54              for o in observers: 
 55                  o.callback(None) 
  56   
 58          """Return a Deferred that will fire (with None) when the call queue 
 59          is completely empty.""" 
 60          if not self._events and not self._in_turn: 
 61              return defer.succeed(None) 
 62          d = defer.Deferred() 
 63          self._flushObservers.append(d) 
 64          return d 
   65   
 66   
 67  _theSimpleQueue = _SimpleCallQueue() 
 68   
 70      """This is the eventual-send operation, used as a plan-coordination 
 71      primitive. The callable will be invoked (with args and kwargs) in a later 
 72      reactor turn. Doing 'eventually(a); eventually(b)' guarantees that a will 
 73      be called before b. 
 74   
 75      Any exceptions that occur in the callable will be logged with log.err(). 
 76      If you really want to ignore them, be sure to provide a callable that 
 77      catches those exceptions. 
 78   
 79      This function returns None. If you care to know when the callable was 
 80      run, be sure to provide a callable that notifies somebody. 
 81      """ 
 82      _theSimpleQueue.append(cb, args, kwargs) 
  83   
 84   
 86      """This returns a Deferred which will fire in a later reactor turn, after 
 87      the current call stack has been completed, and after all other deferreds 
 88      previously scheduled with callEventually(). 
 89      """ 
 90      d = defer.Deferred() 
 91      eventually(d.callback, value) 
 92      return d 
  93   
 95      """This returns a Deferred which fires when the eventual-send queue is 
 96      finally empty. This is useful to wait upon as the last step of a Trial 
 97      test method. 
 98      """ 
 99      return _theSimpleQueue.flush() 
 100   
102      """This sets the reactor used to schedule future events to r.  If r is None 
103      (the default), the reactor is reset to its default value. 
104   
105      This should only be used for unit tests. 
106      """ 
107      if r is None: 
108          r = reactor 
109      _theSimpleQueue._reactor = r 
 110