views:

37

answers:

1

Hi Guys!

I know that twisted will not "wait"... I am working with an XMPP client to exchange data with an external process. I send an request and need to fetch the corresponding answer. I use a sendMessage to send my request to the server. When the server answers a onMessage method will receive it and check if it an answer to a request (not necessarily the one I am looking for) and puts any answer in a stack. As return to my sendRequest I want to return the results, so I would like to pop the response to my request from the stack and return. I read about threads, defers, callbacks and conditionals, tried a lot of the examples and none is working for me. So my example code here is very stripped down pseudo-code to illustrate my problem. Any advice is appreciated.

class Foo(FooMessageProtocol):
    def __init__(self, *args, **kwargs):
        self.response_stack = dict()
        super(Foo, self).__init__(*args, **kwargs)    


    def sendRequest(self, data):
        self.sendMessage(id, data)
        # I know that this doesn't work, just to illustrate what I would like to do:
        while 1: 
            if self.response_stack.has_key(id):
               break
               return self.response_stack.pop(id) 


    def receiveAnswers(self, msg):
        response = parse(msg)
        self.response_stack[response['id']] = response
+2  A: 

you can't return the results to sendRequest, because sendRequest can't wait. make sendRequest return a Deferred instead, and fire it when the result arrives.

So the code calling sendRequest can just add a callback to the deferred and it will be called when there's a response.

Something like this (pseudo-code):

class Foo(FooMessageProtocol):
    def __init__(self, *args, **kwargs):
        self._deferreds = {}
        super(Foo, self).__init__(*args, **kwargs)    

    def sendRequest(self, data):
        self.sendMessage(id, data)
        d = self._deferreds[id] = defer.Deferred()
        return d

    def receiveAnswers(self, msg):
        response = parse(msg)
        id = response['id']
        if id in self._deferreds:
            self._deferreds.pop(id).callback(response)
nosklo
Thanks! Two notes to myself: (1) everything is an object and (2) RTFM at least twice! I hadn't got the whole point about deferreds and thanks to your example and the docs I got over that point and managed to solve the problem. Thanks!
daccle