2010-09-03 2 views
3

Je sais que twisted n'attendra pas ... Je travaille avec un client XMPP pour échanger des données avec un processus externe. J'envoie une demande et j'ai besoin d'aller chercher la réponse correspondante. J'utilise un sendMessage pour envoyer ma requête au serveur. Lorsque le serveur répond à une méthode onMessage, il la reçoit et vérifie s'il s'agit d'une réponse à une requête (pas nécessairement celle que je recherche) et met une réponse dans une pile. Comme retour à ma sendRequest je veux retourner les résultats, donc je voudrais faire apparaître la réponse à ma demande de la pile et retourner. J'ai lu des discussions, des reports, des rappels et des conditions, j'ai essayé beaucoup d'exemples et aucun ne fonctionne pour moi. Donc mon exemple de code ici est très dépouillé de pseudo-code pour illustrer mon problème. Tout conseil est apprécié.Python Twisted: "attendre" pour qu'une variable soit remplie par un autre événement

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 

Répondre

3

vous ne pouvez pas retourner les résultats à sendRequest, car sendRequest ne peut pas attendre. make sendRequest retourner un Deferred à la place, et le feu lorsque le résultat arrive.

Ainsi, le code appelant sendRequest peut simplement ajouter un rappel au différé et il sera appelé lorsqu'il y a une réponse.

Quelque chose comme ça (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) 
+0

Merci! Deux notes à moi-même: (1) tout est un objet et (2) RTFM au moins deux fois! Je n'avais pas tout compris sur les reports et grâce à votre exemple et les docs j'ai surmonté ce point et j'ai réussi à résoudre le problème. Merci! – daccle

Questions connexes