¿Una alternativa limpia y liviana a los retorcidos de Python?
networking twisted (14)
Hay un buen libro sobre el tema: "Twisted Network Programming Essentials", de Abe Fettig. Los ejemplos muestran cómo escribir código muy Pythonic, y para mí personalmente, no me parece que esté basado en un marco hinchado. Mire las soluciones en el libro, si no están limpias, entonces no sé qué significa limpiar.
Mi único enigma es el mismo que tengo con otros marcos, como Ruby. Me preocupa, ¿se escala? No me gustaría comprometer a un cliente con un marco que va a tener problemas de escalabilidad.
Hace mucho tiempo que escribí una araña web que multiproceso para permitir que se produzcan solicitudes simultáneas al mismo tiempo. Eso fue en mi juventud de Python, en los días previos a que supiera acerca de la GIL y los problemas asociados que crea para el código de multiproceso (IE, la mayoría de las veces las cosas simplemente se serializan) ...
Me gustaría volver a trabajar este código para hacerlo más robusto y tener un mejor desempeño. Básicamente, hay dos formas en que podría hacer esto: podría usar el nuevo módulo de multiprocesamiento en 2.6+ o podría optar por un modelo de reactor / evento de algún tipo. Preferiría hacerlo más tarde, ya que es mucho más simple y menos propenso a errores.
Así que la pregunta se relaciona con el marco que mejor se adapte a mis necesidades. La siguiente es una lista de las opciones que conozco hasta ahora:
- Twisted : el abuelo de los armazones de los reactores de Python: parece complejo y un poco abultado. Curva de aprendizaje empinada para una pequeña tarea.
- Eventlet : De los chicos de lindenlab . Marco basado en Greenlet que está orientado a este tipo de tareas. Sin embargo, eché un vistazo al código y no es demasiado bonito: no cumple con pep8, está salpicado de impresiones (¿por qué la gente hace esto en un marco?), La API parece un poco inconsistente.
- PyEv : Inmaduro, no parece que haya nadie usándolo ahora, aunque está basado en libevent, por lo que tiene un fondo sólido.
- asyncore : De la stdlib: über de bajo nivel, parece un montón de trabajo de piernas involucrado solo para hacer que algo despegue.
- tornado : aunque este es un producto orientado a servidores diseñado para servidores de sitios web dinámicos, sí cuenta con un cliente HTTP asíncrono y un ioloop simple. Parece que podría hacer el trabajo pero no para lo que estaba destinado. [edición: desafortunadamente, no se ejecuta en Windows, lo cual es muy importante para mí, es un requisito para mí admitir esta plataforma aburrida]
¿Hay algo que haya echado de menos? ¡Seguramente debe haber una biblioteca por ahí que se ajuste al punto óptimo de una biblioteca de red asíncrona simplificada!
[edit: intgr gracias a intgr por su puntero a esta página . Si se desplaza hasta el final, verá que hay una buena lista de proyectos que intentan abordar esta tarea de una u otra manera. En realidad, parece que las cosas realmente han avanzado desde el inicio de Twisted: ahora la gente parece preferir una solución basada en la co-routine lugar de una solución tradicional orientada al reactor / devolución de llamada. Los beneficios de este enfoque son más claros y directos. Ciertamente descubrí que en el pasado, especialmente cuando trabajo con boost.asio en C ++, el código basado en la devolución de llamadas puede llevar a diseños que pueden ser difíciles de seguir y que son relativamente poco claros. El ojo inexperto. El uso de co-rutinas le permite escribir código que parece un poco más sincrónico al menos. ¡Supongo que ahora mi tarea es averiguar cuál de estas muchas bibliotecas me gusta y dale una oportunidad! Me alegro de que pregunte ahora ...]
[edición: tal vez sea de interés para cualquiera que haya seguido o se haya topado con esta pregunta o se preocupe por este tema en cualquier sentido: encontré una gran reseña del estado actual de las herramientas disponibles para este trabajo]
He empezado a usar trenzado para algunas cosas. La belleza de esto casi es porque está "hinchado". Hay conectores para cualquiera de los protocolos principales que hay. Puede tener un bot Jabber que tomará los comandos y los publicará en un servidor irc, los enviará por correo electrónico a alguien, ejecutará un comando, leerá desde un servidor NNTP y controlará una página web para detectar cambios. La mala noticia es que puede hacer todo eso y puede hacer las cosas demasiado complejas para tareas sencillas, como explicó el OP. La ventaja de python es que solo incluye lo que necesita. Entonces, si bien la descarga puede ser de 20 MB, solo puede incluir 2 MB de bibliotecas (que aún son muchas). Mi mayor queja con Twist es que incluyen ejemplos, cualquier cosa más allá de un servidor TCP básico que está por su cuenta.
Aunque no es una solución de Python, últimamente he visto que node.js ha ganado mucha más tracción. De hecho, he considerado buscar proyectos más pequeños, pero me estremezco cuando escucho javascript :)
Le invitamos a echar un vistazo a PyWorks, que tiene un enfoque muy diferente. Permite que las instancias de objetos se ejecuten en su propio subproceso y hace que las funciones de llamada a ese objeto sean asíncronas.
Simplemente deje que una clase herede de Task en lugar de object y es async, todas las llamadas a métodos son Proxies. Los valores de retorno (si los necesita) son proxies futuros.
res = obj.method( args )
# code continues here without waiting for method to finish
do_something_else( )
print "Result = %d" % res # Code will block here, if res not calculated yet
PyWorks se puede encontrar en http://bitbucket.org/raindog/pyworks
Me gustó el módulo de Python de concurrence que se basa en microthreads Python sin pila o en Greenlets para enhebrar de forma liviana. Todas las E / S de red de bloqueo se realizan de forma transparente asíncrona a través de un solo bucle libevent
, por lo que debería ser casi tan eficiente como un servidor asíncrono real.
Supongo que es similar a Eventlet de esta manera.
El inconveniente es que su API es bastante diferente de los módulos de sockets
/ threading
de Python; necesita volver a escribir un poco de su aplicación (o escribir una capa de compatibilidad de compatibilidad)
Edición: parece que también hay Cogen , que es similar, pero utiliza los generadores mejorados de Python 2.5 para sus coroutines, en lugar de Greenlets. Esto lo hace más portátil que la concurrencia y otras alternativas. La E / S de red se realiza directamente con epoll / kqueue / iocp.
Nicholas Piël compiló una comparación realmente interesante de dichos marcos en su blog: ¡vale la pena leerla!
Ninguna de estas soluciones evitará el hecho de que GIL previene el paralelismo de la CPU; son solo mejores maneras de obtener el paralelismo de E / S que ya tiene con subprocesos. Si cree que puede hacer mejor IO, por todos los medios procure uno de estos, pero si su cuello de botella está en el procesamiento de los resultados, aquí nada le ayudará, excepto el módulo de multiprocesamiento.
No me atrevería a llamar a Twisted hinchado, pero es difícil envolver la cabeza. Evité realmente asentarme en un aprendizaje durante bastante tiempo, ya que siempre quise algo un poco más fácil para "tareas pequeñas".
Sin embargo, ahora que he trabajado un poco más, debo decir que tener todas las baterías incluidas es MUY bueno.
Todas las otras bibliotecas asíncronas con las que he trabajado terminan siendo mucho menos maduras de lo que parecen. El bucle de eventos de Twisted es sólido.
No estoy seguro de cómo resolver la curva de aprendizaje retorcida empinada. Podría ayudar si alguien lo descompusiera y limpiara algunas cosas, como eliminar todos los cruces de compatibilidad hacia atrás y los proyectos muertos. Pero esa es la naturaleza del software maduro, supongo.
Si solo desea una biblioteca de solicitudes HTTP simplificada y liviana, me parece que Unirest realmente bueno
También prueba Syncless . Está basado en coroutine (por lo que es similar a Concurrence, Eventlet y gevent). Implementa reemplazos no bloqueantes para socket.socket, socket.gethostbyname (etc.), ssl.SSLSocket, time.sleep y select.select. Es rápido. Necesita Stackless Python y libevent. Contiene una extensión de Python obligatoria escrita en C (Pyrex / Cython).
Twisted es complejo, tienes razón en eso. Torcido no está hinchado.
Si echa un vistazo aquí: http://twistedmatrix.com/trac/browser/trunk/twisted encontrará una suite organizada, completa y muy bien probada de muchos protocolos de Internet, así como un código de ayuda para escribir. y desplegar aplicaciones de red muy sofisticadas. Yo no confundiría la hinchazón con la amplitud.
Es bien sabido que la documentación retorcida no es la más fácil de usar desde el primer vistazo, y creo que esto aleja a un número desafortunado de personas. Pero Twisted es increíble (IMHO) si pones el tiempo. Lo hice, y valió la pena, y recomendaría a otros que intenten lo mismo.
Whizzer es un pequeño marco de socket asíncrono que utiliza pyev. Es muy rápido, principalmente por Pyev. Intenta proporcionar una interfaz similar como retorcida con algunos cambios leves.
gevent es eventlet limpiado .
En cuanto a API, sigue las mismas convenciones que la biblioteca estándar (en particular, los módulos de subprocesamiento y multiprocesamiento) donde tiene sentido. Así que tienes cosas familiares como Queue y Event con las que trabajar.
Solo es compatible con libevent ( actualización: libev desde 1.0 ) como implementación del reactor, pero lo aprovecha al máximo, con un servidor WSGI rápido basado en libevent-http y resolviendo consultas de DNS a través de libevent-dns en lugar de usar un grupo de subprocesos como la mayoría de las bibliotecas. hacer. ( actualización: desde 1.0 c-ares se usa para hacer consultas de DNS asíncronas; la agrupación de subprocesos también es una opción).
Al igual que eventlet, hace que las devoluciones de llamada y los diferidos sean innecesarios mediante el uso de greenlets .
Echa un vistazo a los ejemplos: descarga simultánea de varias URL , webchat de sondeo largo .
Confirmo la bondad de syncless . Puede usar libev (la versión más nueva, más limpia y con mejor rendimiento de libevent). Algunas veces, no tiene tanto apoyo como Libevent, pero ahora el proceso de desarrollo va más allá y es muy útil.