[Twisted-Python] newbie -- trying to do async ldap operations
Jp Calderone
exarkun at intarweb.us
Tue Apr 22 20:51:54 EDT 2003
On Tue, Apr 22, 2003 at 06:19:28PM -0500, Allan Streib wrote:
> First to set my perspective -- I never heard of Twisted before two days
> ago.
>
> I have an XMLRPC server built with the Medusa framework. I am looking at
> moving the methods to Twisted in order to take advantage of Deferreds, SSL
> support, and based on my brief exposure, the overall framework seems
> cleaner.
>
> This is a simplification, but to keep this short I have an XMLRPC method
> that returns results from an LDAP search. Currently the searches are
> synchronous but they are fast enough that it has not been a problem. Now
> I need to expand the search filter options which will (could) result in a
> slower search.
>
> The OpenLDAP API (and python-ldap) supports asynchronus searching. Sounds
> perfect. A call to ldap.search_s() returns a message ID which is later
> used in a call to result() to get the results. ldap.result() takes the
> message ID, and a timeout argument which if zero is in effect a poll.
>
> So what I want is for my XMLRPC method to invoke search_s and get the
> message ID. Then create a defered and provide its callback and the
> message ID to something that will poll ldap.result() until it returns
> results (if results are not ready it will return [None, None]) and then
> pass those to the callback. Here's where I get confused; I think the call
> to ldap.result() needs to be done by reactor somehow since ldap.result()
> may need to be called repeatedly before results are ready) but I'm not
> sure.
>
> The whole deferred light bulb has not quite come on for me yet, so I
> appreciate any guidance. The defer HOWTO examples all use something like
> reactor.callLater() to represent a "delayed result" which is not really
> helping me. The XMLRPC example of returning a defered just returns
> defer.succeed("hello"), again not quite a rich enough example.
>
> I thought about adapting the adbapi stuff for LDAP, but the notion is in
> my head that I should be able to do this without threads since the ldap
> API supports async operations.
>
Here's something that might help (note that I am not familiar with the
python-ldap API, so I'm just guessing at how it is laidd out):
from twisted.internet import reactor, defer
class LDAPQueryTracker:
def __init__(self):
self._ids = {}
# Wrapper around python-ldap's search function
# returns a Deferred whose callback will be invoked
# with the result
def search(self, args):
id = ldap.search_s(args)
self._ids[id] = defer.Deferred()
reactor.callLater(0, self.poll)
return self._ids[id]
# A method to poll any "live" queries,
# and to schedule another poll if there are any
# remaining outstanding queries
def poll(self):
for (id, d) in self._ids.items():
r = ldap.result(id, timeout=0):
if r is not None:
del self._ids[id]
d.callback(r)
if self._ids:
reactor.callLater(0, self.poll)
# Two trivial callbacks to handle the result
def printResult(result):
print 'LDAP result:', result
def printFailure(failure):
print 'LDAP failed!'
failure.printTraceback()
# Make a tracker, perform a query, and add some callbacks
qt = LDAPQueryTracker()
d = qt.search("humm, I have no idea what an ldap query looks like")
d.addCallbacks(printResult, printFailure)
# Do it.
reactor.run()
Hope this helps,
Jp
--
"If you find a neighbor in need, you're responsible for serving that
neighbor in need, you're responsible for loving a neighbor just like you'd
like to love yourself." -- George W. Bush, Sept. 16, 2002
--
up 33 days, 21:03, 5 users, load average: 2.01, 1.90, 1.90
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://twistedmatrix.com/pipermail/twisted-python/attachments/20030422/f76cf7e1/attachment.pgp
More information about the Twisted-Python
mailing list