While it is not possible to interrupt threads, Deferred can be stopped using the cancel function, which I think is available in Twisted 10.1.0 and later.
I used the following class to do Deferrals that refer to a specific function if Deferment has not quit after a while. This may be useful for someone who has the same question as the OP subject.
EDIT: As suggested below, it is best not to inherit from defer.Deferred . So I changed the code to use a wrapper that achieves the same effect.
class DeferredWrapperWithTimeout(object): ''' Holds a deferred that allows a specified function to be called-back if the deferred does not fire before some specified timeout. ''' def __init__(self, canceller=None): self._def = defer.Deferred(canceller) def _finish(self, r, t): ''' Function to be called (internally) after the Deferred has fired, in order to cancel the timeout. ''' if ( (t!=None) and (t.active()) ): t.cancel() return r def getDeferred(self): return self._def def addTimeoutCallback(self, reactr, timeout, callUponTimeout, *args, **kw): ''' The function 'callUponTimeout' (with optional args or keywords) will be called after 'timeout' seconds, unless the Deferred fires. ''' def timeoutCallback(): self._def.cancel() callUponTimeout(*args, **kw) toc = reactr.callLater(timeout, timeoutCallback) return self._def.addCallback(self._finish, toc)
Example callback before timeout:
from twisted.internet import reactor from DeferredWithTimeout import * dw = DeferredWrapperWithTimeout() d = dw.getDeferred() def testCallback(x=None): print "called" def testTimeout(x=None): print "timedout" d.addCallback(testCallback) dw.addTimeoutCallback(reactor, 20, testTimeout, "to") reactor.callLater(2, d.callback, "cb") reactor.run()
Prints "called" and nothing more.
Example timeout before callback:
from twisted.internet import reactor from DeferredWithTimeout import * dw = DeferredWrapperWithTimeout() d = dw.getDeferred() def testCallback(x=None): print "called" def testTimeout(x=None): print "timedout" d.addCallback(testCallback) dw.addTimeoutCallback(reactor, 20, testTimeout, "to") reactor.run()
Prints a "timeout" after 20 seconds and nothing more.