[Twisted-Python] ldaptor's LDAPClient.send_multiResponse not dealing with chained deferreds, patch
Michael Torrie
torriem at gmail.com
Sat May 3 21:03:29 EDT 2008
This message is probably for Tv.
I have a situation where the callback to a
LDAPClient.send_multiResponse() call needs to do a bunch of work that I
want to split up over several functions, using deferred chaining. What
I want to do is something like this (this in conjunction with an LDAP
proxy server I am writing using Twisted and ldaptor):
d = self.client.send_multiResponse(request, got_response)
then later:
def got_response(response):
# get a list of other things to do with the response
d = do_stuff_with_response(response)
d.addCallback(finish)
return d
def finish(response):
# we're done
return isinstance(response, (
pureldap.LDAPSearchResultDone,
pureldap.LDAPBindResponse,
))
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.
The problem is that in ldapclient.py, line 171, we have:
# Return true to mark request as fully handled
if handler(msg.value, *args, **kwargs):
del self.onwire[msg.id]
When handler() returns a deferred object, after the reactor processes
the chain the value is a Deferred object, not True or False, even though
the value of the deferred object may be True or False. Hence the del
self.onwire[msg.id] always executes, which when dealing with search
result entries is a problem as they all share the same id. I made a
quick hack to fix this:
-----------------------------------------------------------
--- /tmp/ldapclient.py 2008-05-03 18:53:26.000000000 -0600
+++ ldaptor/protocols/ldap/ldapclient.py 2008-05-03
18:58:07.000000000 -0600
@@ -168,7 +168,14 @@
assert args is not None
assert kwargs is not None
# Return true to mark request as fully handled
- if handler(msg.value, *args, **kwargs):
+ result = handler(msg.value, *args, **kwargs)
+
+ try:
+ result = result.result
+ except AttributeError:
+ pass
+
+ if result:
del self.onwire[msg.id]
##Bind
----------------------------------------------------------
Is this an acceptable way to do this?
More information about the Twisted-Python
mailing list