Package ZenUtils :: Module Step
[hide private]
[frames] | no frames]

Source Code for Module ZenUtils.Step

 1  ########################################################################### 
 2  # 
 3  # This program is part of Zenoss Core, an open source monitoring platform. 
 4  # Copyright (C) 2007, Zenoss Inc. 
 5  # 
 6  # This program is free software; you can redistribute it and/or modify it 
 7  # under the terms of the GNU General Public License version 2 as published by 
 8  # the Free Software Foundation. 
 9  # 
10  # For complete information please visit: http://www.zenoss.com/oss/ 
11  # 
12  ########################################################################### 
13   
14  __doc__='''Step 
15   
16  Utility for chaining defered actions. 
17   
18  ''' 
19   
20  from twisted.internet import reactor 
21  import twisted.internet.defer as defer 
22   
23 -def Step(iterable):
24 ''' Step through iterable looking for deferreds. Whenever a deferred is 25 encountered wait until it is called before continuing through iterable. 26 27 Iterable is usually a generator function that yields a defered 28 anytime it wants to wait for that deferred to trigger before 29 continuing execution. 30 ''' 31 def doSteps(result): 32 # Depending on closure for value of iterable and finalD. 33 # If this causes problems we can pass them as arguments 34 # to doSteps and pass them in the addCallback(doSteps..) call. 35 # 36 # We don't actually use result anywhere here unless we are done 37 # iterating through iterable, in which case result becomes the 38 # result for the finalD deferred. 39 # Code within the iterable that needs the result of the previously 40 # yielded defered can get it directly from that deferred's result 41 # attribute. 42 for result in iterable: 43 # Keep getting items from iterable (the generator) until 44 # one returns a deferred. Then add this function as a 45 # callback to that deferred and return from the function. 46 if isinstance(result, defer.Deferred): 47 result.addCallback(doSteps) 48 return result 49 finalD.callback(result) 50 return result
51 52 # Make sure we have an iterable 53 if not hasattr(iterable, 'next'): 54 if hasattr(iterable, '__iter__'): 55 iterable = iter(iterable) 56 else: 57 raise 'Must pass an iterable object to step' 58 59 # finalD is the deferred that will trigger when iterable is exhausted 60 finalD = defer.Deferred() 61 62 # start consuming the iterable 63 doSteps(None) 64 65 return finalD 66 67
68 -class Test:
69
70 - def foo(self, n):
71 d = defer.Deferred() 72 reactor.callLater(2, d.callback, n) 73 return d
74 75
76 - def sequence(self):
77 d1 = self.foo(1) 78 print 'yielding d1 from sequence' 79 yield d1 80 r1 = d1.result 81 d2 = self.foo(r1 + 1) 82 print 'yielding d2 from sequence' 83 yield d2 84 r2 = d2.result 85 print 'yielding final result from sequence' 86 yield r2
87 88
89 - def myCallback(self, r):
90 print 'final deferred returned %s' % `r`
91 92
93 - def go(self):
94 myD = Step(self.sequence()) 95 myD.addCallback(self.myCallback) 96 reactor.callLater(10, reactor.stop) 97 reactor.run()
98