1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 __doc__='''Driver.py
16
17 Run generators that produce Deferreds.
18
19 twisted.flow has something like this, except I cannot understand it.
20
21 $Id$
22 '''
23
24 __version__ = "$Revision$"[11:-2]
25
26
27 from twisted.internet import defer, reactor
28 from twisted.python import failure
29
31 "Walk an iterable that returns a deferred."
32
36
37 - def drive(self, iterable):
38 "Call the iterable and set up callbacks to finish"
39 self.iter = iterable
40 self._next()
41 return self.defer
42
51
60
62 "Store the result of the last deferred for use in next()"
63 self.result = result
64 self._next()
65
67 '''Typical use of Driver class:
68
69 def walk(driver):
70 yield thing1()
71 print "Thing 1 is", driver.next()
72 yeild thing2()
73 print "Thing 2 is", driver.next()
74
75 drive(walk)
76
77 '''
78 d = Driver()
79 return d.drive(callable(d))
80
81
83 "Drive the callable at a later time"
84 d = defer.Deferred()
85 def driveAgain():
86 drive(callable).chainDeferred(d)
87 reactor.callLater(secs, driveAgain)
88 return d
89
90
92 lst = []
93 def loop(d):
94 for i in range(10):
95 yield defer.succeed(i)
96 lst.append(d.next())
97 def final(v):
98 assert lst[-1] == v
99 drive(loop).addCallback(final)
100 assert lst == range(10)
101 def unloop(d):
102 yield defer.fail(ZeroDivisionError('hahaha'))
103 d.next()
104 def checkError(err):
105 assert isinstance(err.value, ZeroDivisionError)
106 drive(unloop).addErrback(checkError)
107
108
109 if __name__ == '__main__':
110 test()
111