30 votes

Programmation asynchrone en Python Twisted

J'ai du mal à développer un proxy inverse dans Twisted. Cela fonctionne, mais cela semble excessivement complexe et alambiqué. Il y a tellement de choses qui ressemblent à du vaudou.

Y a-t-il des simple, solide des exemples de structure de programme asynchrone sur le web ou dans les livres ? Une sorte de guide des meilleures pratiques ? Lorsque je termine mon programme, j'aimerais être capable de voir la structure d'une manière ou d'une autre, et non pas regarder un bol de spaghettis.

5 votes

J'espère que vous avez plus de chance avec le twist. C'est actuellement l'un de mes frameworks préférés.

65voto

Glyph Points 17756

Twisted contient un un grand nombre d'exemples . L'un d'entre eux en particulier, le "tutoriel "évolution du doigt contient une explication détaillée de la manière dont un programme asynchrone se développe à partir d'un tout petit noyau jusqu'à un système complexe comportant de nombreuses pièces mobiles. Un autre tutoriel qui pourrait vous intéresser est celui qui traite simplement de serveurs d'écriture .

La chose essentielle à garder à l'esprit concernant Twisted, ou même d'autres bibliothèques de mise en réseau asynchrone (telles que asynchrone , MINA ou ACE ), c'est que votre code n'est invoqué que lorsque quelque chose se produit. La partie que j'ai entendue le plus souvent ressembler à du "voodoo" est la gestion des callbacks : 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 renvoient immédiatement 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, ni de "vaudou" dans les rappels. Au niveau le plus bas, le réacteur se contente de rester assis et d'attendre qu'un petit nombre de choses se produisent :

  1. Les données arrivent sur une connexion (elles appellent dataReceived sur un protocole)
  2. Le temps s'est écoulé (il appellera une fonction enregistrée auprès de callLater ).
  3. Une connexion a été acceptée (elle appelle buildProtocol sur une usine enregistrée avec un listenXXX o connectXXX fonction).
  4. Une connexion a été interrompue (il appellera connectionLost sur le protocole approprié)

Tout programme asynchrone commence par brancher quelques-uns de ces événements, puis lance le réacteur pour attendre qu'ils se produisent. Bien entendu, les événements qui se produisent entraînent d'autres événements qui sont connectés ou déconnectés, et votre programme poursuit ainsi son chemin. Au-delà de cela, la structure des programmes asynchrones n'a rien d'intéressant ou de spécial ; les gestionnaires d'événements et les callbacks sont simplement des objets, et votre code s'exécute 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 des bibliothèques comme Twisted, la fonction dans la boucle principale n'est pas sleep mais un appel du système d'exploitation comme select() o poll() tel qu'exposé par un module comme le module Python select . Je dis "comme" select car il s'agit d'une API qui varie beaucoup d'une plate-forme à l'autre, et presque chaque boîte à outils d'interface graphique possède sa propre version. Twisted fournit actuellement une interface abstraite pour 14 variations différentes sur ce thème. La chose commune qu'une telle API fournit est un moyen de dire "Voici une liste d'événements que j'attends. Endors-toi jusqu'à ce que l'un d'eux se produise, puis réveille-toi et dis-moi lequel c'était".

0voto

Sargun Dhillon Points 831

Si vous ne cherchez pas à utiliser le twisted, il y a un excellent guide que j'ai utilisé il y a quelque temps. Voici le lien vers le site .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X