[Twisted-Python] ldaptor's LDAPClient.send_multiResponse not dealing with chained deferreds, patch
torriem at gmail.com
Sat May 3 22:22:25 EDT 2008
Jean-Paul Calderone wrote:
>> However, this doesn't work, because the send_multiResponse() method of
>> LDAPClient isn't expecting the handler to return a deferred, even though
>> if I do return a deferred the reactor does handle it properly, chaining
>> the deferreds and their callbacks.
> You don't need to return the Deferred in order for the code and event
> sources associated with it to cause it to eventually fire. Returning
> it doesn't do anything more than make it available to the caller. It
> seems this is what you actually want though, so this is just a change
> of perspective not a contradiction of your conclusion.
This stuff is getting kind of confusing for me, I must confess.
Especially because it's hard to explain exactly what I'm doing without
posting a very large code example (with lots of supporting modules). I
may work on a minimal example, based on the proxy.py that ldaptor ships
with to demonstrate this.
So yes, the handler is just a callback attached to a deferred that has
already fired -- the deferred itself is irrelevant. This deferred was
originally created by the LDAPClient.send_multiResponse() method, and it
fires when a response to the request comes in (there can be more than
one response, if the request was a search). This function is a bit
confusing because it creates a deferred object that it returns to me,
but also takes a handler function as an argument. I've tried to add my
additional processing routines to this particular deferred as a
callback, but that does not work. I think if I could get this to work,
that might be the better way to go.
In the meantime, in the handler I pass to send_multiResponse(), I need
to generate a new deferred chain that has parts of it deferred to other
threads, etc. Returning this new deferred from my handler seems ideal,
as the reactor just does the right thing.
> Or, written using the helper function twisted.internet.defer.maybeDeferred,
> def cbHandler(result):
> if result:
> del self.onwire[msg.id]
> result = maybeDeferred(handler, msg.value, *args, **kwargs)
> This correctly handles both Deferred and non-Deferred results. I don't
> have any idea if this change to ldaptor is correct with respect to LDAP
> semantics/requirements or the particular implementation details of the
> code in question here, though.
Yes, this would seem the correct thing to do! I'll have to work out a
patch that does this and see where we're at.
More information about the Twisted-Python