[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