[Twisted-Python] A pseudo-deferred class that can be canceled
Terry Jones
terry at jon.es
Tue Jan 5 05:47:50 MST 2010
Hi again Glyph, Andrew
Below is a simpler and more flexible ControllableDeferred class.
The idea is simple: you want a deferred that you can call/errback yourself,
and which you can also deactivate so that it never fires. This is done by
manipulating two normal deferreds (self, and a deferred received from
maybeDeferred). This ControllableDeferred class sits in the middle and will
(a) pass on the normal result (via chainDeferred) if it arrives first, or
(b) if called by the user, fire with the user-supplied value, or (c) if
deactivated by the user, never fire. In cases b and c it will ignore the
result (if any ever arrives) from the function originally called.
In summary, this provides two things you can't ordinarily do when you get a
deferred (d) back from calling a function:
- Call d yourself, thereby firing it immediately.
- Deactivate d, so that it never fires.
The code below could be a bit more sophisticated. E.g., it could tell you
if you try to call a deferred you've deactivated. It should probably use an
attribute name other than _called. I've kept it sparse for now though so
the general idea is clearer. I changed its name to reflect that the
deferred is more controllable.
Terry
---
from twisted.internet import defer
class ControllableDeferred(defer.Deferred):
def __init__(self, f, *args, **kw):
defer.Deferred.__init__(self)
self._called = False
self._calld = defer.maybeDeferred(f, *args, **kw).addBoth(self._fire)
def _fire(self, ign):
if not self._called:
self._called = True
self._calld.chainDeferred(self)
def callback(self, result):
if not self._called:
self._called = True
defer.Deferred.callback(self, result)
def errback(self, fail=None):
if not self._called:
self._called = True
defer.Deferred.callback(self, fail)
def deactivate(self):
self._called = True
More information about the Twisted-Python
mailing list