Why can't we call a Twisted deferred twice?

python, twisted

Solution

A `Deferred` represents the result of a request which may be available (now or in the future) but is not definitely available now.

Results flow through `Deferred`s, via their callback chain. For example, in a synchronous program, you might have something like:

response_bytes = make_request(...)
response_dict = parse_json(response_bytes)
response_object = construct_object(response_dict)
return response_object.method()

Translated to code that returns a `Deferred`, this is:

response_bytes_later = make_request_async(...)
response_dict_later = response_bytes_later.addCallback(parse_json)
response_object_later = response_dict_later.addCallback(construct_object)
return response_object_later.addCallback(lambda response_object:
                                         response_object.method())

Asking why you can't fire (or "call back") the `Deferred` returned by `make_request_async` is similar to asking why you can't have `make_request` return multiple times to cause the request to be reissued. If you want to issue the request again in the synchronous version, you have to call `make_request` again (and get a new result). If you want to issue the request again in the asynchronous version, you have to call `make_request_async` again (and get a new `Deferred`).

Problem

From the following guide: http://krondo.com/blog/?p=1682 Deferreds help us avoid one of the pitfalls we identified with callback programming. When we use a deferred to manage our callbacks, we simply can’t make the mistake of calling both the callback and the errback, or invoking the callback twenty-seven times. We can try, but the deferred will raise an exception right back at us, instead of passing our mistake onto the callbacks themselves Can anyone give me a better explanation? I noticed that it wouldn't work anyways because in most cases in this tutorial the end callback also calls reactor.stop(). But why though doesn't it make sense to call a deferred twice? Why is it any different than calling a chain of methods again?

Original source