2008-09-17 15 views
29

Tengo problemas para desarrollar un proxy inverso en Twisted. Funciona, pero parece demasiado complejo y enrevesado. Mucho se siente como vudú.Programación asincrónica en Python Twisted

¿Hay simples sólidos ejemplos de la estructura del programa asíncrono, en la web o en los libros? ¿Una especie de guía de mejores prácticas? Cuando complete mi programa, me gustaría seguir viendo la estructura de alguna manera, sin mirar un plato de espagueti.

+5

Espero que estés teniendo mejor suerte con Twisted. Actualmente es uno de mis frameworks favoritos. – Dustin

Respuesta

0

Si no está buscando usar retorcido, había una gran guía que utilicé hace un tiempo. Aquí está el link to it.

64

Twisted contiene large number of examples. Uno en particular, el "evolution of Finger" tutorial, contiene una explicación detallada de cómo un programa asíncrono crece desde un kernel muy pequeño hasta un sistema complejo con muchas partes móviles. Otro que podría interesarle es el tutorial sobre simplemente writing servers.

La clave a tener en cuenta sobre Twisted, o incluso otras bibliotecas de redes asíncronas (tales como asyncore, MINA o ACE), es que su código sólo se invoca cuando ocurre algo. La parte que he escuchado más a menudo suena como "vudú" es la gestión de devoluciones de llamadas: por ejemplo, Deferred. Si está acostumbrado a escribir código que se ejecuta en línea recta y solo llama a funciones que regresan inmediatamente con resultados, la idea de esperar que algo le devuelva la llamada podría ser confusa. Pero no hay nada mágico, no hay "vudú" sobre devoluciones de llamadas. En el nivel más bajo, el reactor es simplemente sentarse alrededor y esperar a que uno de un pequeño número de cosas que suceden:

  1. Los datos llegan en una conexión (se llamará dataReceived en un Protocolo)
  2. El tiempo ha pasado (llamará a una función registrada con callLater).
  3. Se ha aceptado una conexión (llamará a buildProtocol en una fábrica registrada con una función listenXXX o connectXXX).
  4. Una conexión se ha caído (se llamará connectionLost en el protocolo correspondiente)

Cada programa comienza asíncrono mediante la conexión de algunos de estos eventos y luego dar comienzo al reactor para esperar a que sucedan. Por supuesto, los eventos que suceden llevan a más eventos que se conectan o desconectan, por lo que su programa sigue su camino feliz. Más allá de eso, no hay nada especial acerca de la estructura del programa asíncrono que sea interesante o especial; los controladores de eventos y las devoluciones de llamada son solo objetos, y su código se ejecuta de la manera habitual.

Aquí hay un simple "motor de eventos" que muestra lo simple que es este proceso.

# 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!' 

En el núcleo de bibliotecas como Twisted, la función en el bucle principal no es sleep, sino una llamada de sistema operativo como select() o poll(), como expuesto por un módulo como the Python select module. Digo "me gusta" select, porque esta es una API que varía mucho entre las plataformas, y casi todas las herramientas GUI tienen su propia versión. Twisted actualmente proporciona una interfaz abstracta para 14 variaciones diferentes sobre este tema. Lo común que ofrece una API así es proporcionar una forma de decir "Aquí hay una lista de eventos que estoy esperando. Dormir hasta que uno de ellos suceda, luego despertar y decirme cuál de ellos fue."

Cuestiones relacionadas