1
2
3
4 from twisted.internet import reactor, defer
5 from twisted.python import log
6
8
9 _reactor = reactor
10
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
23 self._timer = None
24 self._in_turn = True
25
26
27
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
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
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
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
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
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