La semana pasada hablábamos de la programación dirigida por eventos donde se hacía una introducción a la arquitectura evento -> disparador -> manejador a los frameworks de desarrollo GUI y por último a la programación asíncrona.
Hoy voy a hacer una introducción a la programación asíncrona con Twisted el framework de red para programación asíncrona dirigida por eventos. Twisted está escrito en Python y se distribuye de forma totalmente libre bajo la licencia MIT.
Su primera versión fue liberada el veintidós de octubre del 2002 y está considerada una de las librerías de sockets asíncronos más rápidas del panorama. Su creador es Glyph Lefkowitz un gurú dentro de la comunidad de Python.
Arquitectura Modular
Twisted se divide en 7 módulos además del core:
-
conch que implementa el protocolo SSH
-
lore que implementa un sistema completo de documentación
-
mail que implementa protocolos relacionados con el correo electrónico como SMTP e IMAP
-
names que implementa el protocolo DNS
-
trial un framework de testsing sobre PyUnit que soporta programación asíncrona
-
web que implementa el protocolo HTTP
-
words que implementa diferentes clientes, servidores y protocolos de mensajería instanánea
Protocolos
Twisted implementa multitud de protocolos que podemos utilizar en nuestras aplicaciones de forma sencilla y asíncrona, contiene un servidor web, numerosos clientes de mensajería instantanea, servidores de chat, servidores y clientes de correo, servidores y clientes SSH y mucho más.
Twisted está formado por subproyectos independientes que pueden ser usados de forma individual junto al core de la librería.
Separación de protocolos y capas
Twisted está diseñado con el fin de separar completamente los protocolos lógicos (SMTP, HTTP, SSH...) y el transporte en capas físicas (sockets o SSL).
La conexión en entre protocolos y capas tiene lugar en el último momento justo antes de que los datos sean entregados a la instancia del protocolo lógico. Es justo en ese momento cuando la capa del protocolo podrá hacer uso de la capa de transporte siempre y cuando sean semánticamente compatibles.
Más allá de los eventos, el Defereed
El concepto principal y que más claramente hay que comprender a la hora de programar con Twisted es el Deferred. De forma abstracta, podemos considerar a un deferred como un valor que aún no ha sido calculado, por ejemplo, por que dicho valor debe ser calculado y devuelto por una operación pendiente en un sistema remoto.
Todo deferred debe estar asociado a un callback y puede estar asociado a su vez a un errback. El deferred invoca a la función callback a la que está asociado cuando dispone de un valor que devolver pasando dicho valor como primer parámetro.
Los callbacks a su vez devuelven eventos que pueden asociarse a otros callbacks creando así secuencias encadenadas de burbujeo de eventos.
Si un callback falla, invoca a la función errback a la que esté asociado en caso de estarlo. Al igual que ocurre con los callbacks, los errbacks pueden encadenar a otros eventos. Cualquier operación de entrada/salida usado en la librería devuelve uno de estos deferreds para su uso.
Cuando usamos deferreds, bien estén estos encadenados o no, la aplicación nunca tendrá la necesidad de bloquearse en espera del retorno de un valor. Los deferreds son en definitiva, una especie de abstracción sobre los threads nativos de Python. Los threads se adhieren al hilo de ejecución principal evitando el uso de locks y semáforos complejos.
Integración con otros bucles de eventos
Twisted puede integrarse con bucles de eventos externos. Su bucle de eventos se denomina reactor
, y usa epoll bajo Linux, kqueue bajo BSD y Mac OS X y IOCP bajo MS Windows. La tabla completa de reactores es la siguiente:
Estado | TCP | SSL | UDP | Threading | Procesos | Scheduling | Plataforma | |
---|---|---|---|---|---|---|---|---|
select() | Estable | S | S | S | S | S | S | Unix, Win32 |
poll | Estable | S | S | S | S | S | S | Unix |
WaitForMultipleObjects (WFMO) for Win32 | Experimental | S | S | S | S | S | S | Win32 |
Input/Output Completion Port (IOCP) for Win32 | Experimental | S | S | N | N | N | S | Win32 |
CoreFoundation | Abandonado | S | S | S | S | S | S | Mac OS X |
epoll | Estable | S | S | S | S | S | S | Linux 2.6 |
GTK+ | Estable | S | S | S | S | S | S | Unix, Win32 |
wx | Experimental | S | S | S | S | S | S | Unix, Win32 |
kqueue | Experimental | S | S | S | S | S | S | FreeBSD |
Algunos de los bucles de eventos con los que es posible la integración son GTK, Qt o Cocoa. Todos ellos proveen a Twisted de la facultad de poder ser usado como capa de soporte de sockets en aplicaciones GUI sin el trauma de añadir una sobrecarga de thread por socket como ocurriría con cualquier otra librería de sockets nativa en Python.
Puede integrarse por ejemplo un servidor web basado en Twisted a cualquier aplicación Qt, GTK o Cocoa entre otros muchos usos. El límite es la imaginación.
Procesos
Twisted no solo ofrece conexión entre servidores a través de la red, también ofrece conexión a procesos locales utilizando prácticamente la misma API. Twsited puede ejecutar otros procesos generando tuberías (pipes) en el proceso hijo y añadiendo estas al reactor del proceso padre por lo que la comunicación entre ambos puede transcurrir de forma asíncrona y sin bloqueos de ningún tipo.
Es necesario escribir un protocolo de proceso que pasarle al constructor de la instancia del objeto necesario (reactor.spawnProcess
) para crear y ejecutar nuevos procesos en Twisted. Los protocolos de procesos son muy similares a los protocolos para sockets y es uno de los puntos fuertes de Twisted su facilidad para escribir e integrar nuevos protocolos para su uso cotidiano.
Conclusión
Hemos hecho una pequeña introducción a la programación asíncrona con Twisted donde hemos repasado los aspectos fundamentales de este framework. En posteriores artículos de la serie aprenderemos paso a paso a construir diferentes clientes y servidores que usen diferentes protocolos y a crear nuevos protocolos y utilizar el resto de la funcionalidad de la librería.
En Genbeta Dev | Introducción a la programación dirigida por eventos
Más Información | Tutoriales básicos de Twisted escritos por Dave Peticolas