Timing-Out a Deferred¶
Twisted’s defer.addTimeout allows a time limit to be set for the resolution of a Deferred. If the Derferred does not resolve in the specified time, it will be Errback-ed with a CancelledError.
When it is useful¶
Deferred objects are not guaranteed to resolve in any concrete amount of time, but often after a reasonable time limit is reached it is reasonable to assume that something has gone wrong and that the Deferred should be cancelled with an error.
As an example, consider an attempt to connect to a remote server. If the connection is taking too long to become established, it may be better to simply cancel the attempt and try again with a different server.
How to use it¶
Example¶
To add a Timeout to a Deferred, simply call addTimeout()
on the Deferred
object.
Below, inside of our unit test, we create a Deferred d
and call its
addTimeout
function, which automatically cancels it in 5 seconds and
uses the reactor to track the passage of time before cancellation.
Deferreds cancelled by addTimeout
raise a TimeoutError
AND, as they
call cancel, a CancelledError
as well. We have added assertions to our unit
test to confirm this behaviour:
from twisted.internet import reactor
from twisted.internet.defer import TimeoutError, CancelledError, Deferred
from twisted.trial import unittest
class DeferredExampleTest(unittest.TestCase):
def testTimeOutIn5(self):
def timeOutIn5() -> Deferred:
d = Deferred()
d.addTimeout(5, reactor)
d.addErrback(print)
return d
# A timed-out Deferred should always raise a TimeoutError
self.assertRaises(TimeoutError, self.addCleanup(timeOutIn5))
self.assertRaises(CancelledError, self.addCleanup(timeOutIn5))
Sample Output¶
Ran 1 test in 10.013s
OK