Package buildbot :: Package util :: Module eventual
[frames] | no frames]

Source Code for Module buildbot.util.eventual

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