2008-09-17 10 views
29

Je rencontre des difficultés pour développer un proxy inverse dans Twisted. Cela fonctionne, mais il semble trop complexe et compliqué. Tellement de cela ressemble à du vaudou.Programmation asynchrone en Python Twisted

Y a-t-il des simples, solides exemples de structure de programme asynchrone sur le Web ou dans les livres? Une sorte de guide des bonnes pratiques? Quand j'aurai terminé mon programme, j'aimerais pouvoir voir la structure d'une façon ou d'une autre, ne pas regarder un bol de spaghetti.

+5

J'espère que vous avez plus de chance avec twisted.Il est actuellement l'un de mes cadres préférés. – Dustin

Répondre

0

Si vous ne cherchez pas à utiliser tordu il y avait un excellent guide que j'ai utilisé un certain temps. Voici le link to it.

64

Twisté contient un large number of examples. Un en particulier, le "evolution of Finger" tutorial, contient une explication détaillée de la façon dont un programme asynchrone se développe à partir d'un très petit noyau jusqu'à un système complexe avec beaucoup de parties mobiles. Un autre qui pourrait vous intéresser est le tutoriel sur simplement writing servers.

La chose à garder à l'esprit sur Twisted, ou même d'autres bibliothèques de réseaux asynchrones (tels que asyncore, MINA ou ACE), est que votre code est invoqué que lorsque quelque chose se passe. La partie que j'ai entendu le plus souvent ressembler à "vaudou" est la gestion des rappels: par exemple, Deferred. Si vous avez l'habitude d'écrire du code qui s'exécute en ligne droite et n'appelle que des fonctions qui retournent immédiatement avec des résultats, l'idée d'attendre que quelque chose vous rappelle peut être déroutante. Mais il n'y a rien de magique, pas de "vaudou" à propos des rappels. Au niveau le plus bas, le réacteur est juste assis autour et attendre un d'un petit nombre de choses à se produire:

  1. arrive données sur une connexion (il appellera dataReceived sur un protocole)
  2. Le temps a passé (il appellera une fonction enregistrée avec callLater).
  3. Une connexion a été acceptée (elle appellera buildProtocol sur une usine enregistrée avec une fonction listenXXX ou connectXXX).
  4. Une connexion est tombé (il appellera connectionLost sur le protocole approprié)

Chaque programme asynchrone démarre en accrochant un peu de ces événements, puis le coup d'envoi du réacteur à attendre qu'ils se produisent. Bien sûr, les événements qui se produisent mènent à plus d'événements qui se connectent ou se déconnectent, et ainsi votre programme continue son bonhomme de chemin. Au-delà de cela, il n'y a rien de spécial au sujet de la structure de programme asynchrone qui soit intéressante ou spéciale; Les gestionnaires d'événements et les rappels ne sont que des objets, et votre code est exécuté de la manière habituelle.

Voici un simple "moteur piloté par les événements" qui vous montre à quel point ce processus est simple.

# Engine 
import time 
class SimplestReactor(object): 
    def __init__(self): 
     self.events = [] 
     self.stopped = False 

    def do(self, something): 
     self.events.append(something) 

    def run(self): 
     while not self.stopped: 
      time.sleep(0.1) 
      if self.events: 
       thisTurn = self.events.pop(0) 
       thisTurn() 

    def stop(self): 
     self.stopped = True 

reactor = SimplestReactor() 

# Application  
def thing1(): 
    print 'Doing thing 1' 
    reactor.do(thing2) 
    reactor.do(thing3) 

def thing2(): 
    print 'Doing thing 2' 

def thing3(): 
    print 'Doing thing 3: and stopping' 
    reactor.stop() 

reactor.do(thing1) 
print 'Running' 
reactor.run() 
print 'Done!' 

Au cœur de bibliothèques comme Twisted, la fonction dans la boucle principale est non sleep, mais un appel de système d'exploitation comme select() ou poll(), comme exposé par un module comme the Python select module. Je dis "comme" select, parce que c'est une API qui varie beaucoup entre les plates-formes, et presque chaque boîte à outils GUI a sa propre version. Twisted fournit actuellement une interface abstraite à 14 variations différentes sur ce thème. La chose commune qu'une telle API fournit est de fournir une façon de dire: «Voici une liste d'événements que j'attends: Allez dormir jusqu'à ce que l'un d'eux se produise, puis réveillez-vous et dites-moi lequel."

Questions connexes