SlideShare una empresa de Scribd logo
1 de 45
Descargar para leer sin conexión
Desarrollando aplicaciones de red con
Twisted
Objetivos
• Mío: aprender, ordenar ideas.
• Para algunos: mostrarles algo que no conocían.
• Para otros: darles una razón para estudiar Python.
• Esto no es un curso de Twisted, es apenas una introducción.
• Si ya sabés Twisted:
• No te voy a contar nada nuevo.
• Tu ayuda en la charla es bienvenida!
Agenda
• Aplicaciones de red
• Twisted: conceptos claves y ejemplos
• Reactor
• Deferreds
• Servidores y clientes
Aplicaciones de red
• LAN/WAN
• Internet (TCP/IP)
• Cliente/Servidor
Capas
Clientes
En la arquitectura C/S el remitente de una solicitud es conocido como cliente.
• Es quien inicia solicitudes o peticiones, tienen por tanto un papel activo en la
comunicación (dispositivo maestro o amo).
• Espera y recibe las respuestas del servidor.
• Por lo general, puede conectarse a varios servidores a la vez.
• Normalmente interactúa directamente con los usuarios finales mediante una interfaz
gráfica de usuario.
Servidores
Al receptor de la solicitud enviada por cliente se conoce como servidor.
• Al iniciarse esperan a que lleguen las solicitudes de los clientes, desempeñan
entonces un papel pasivo en la comunicación (dispositivo esclavo).
• Tras la recepción de una solicitud, la procesan y luego envían la respuesta al
cliente.
• Por lo general, aceptan conexiones desde un gran número de clientes (en ciertos
casos el número máximo de peticiones puede estar limitado).
• No es frecuente que interactúen directamente con los usuarios finales.
Python
• Cuantos de aca entienden esta porción de Python?
def funcion(l, b=42):
for x in l:
if x == b:
print x
numeros = [1, 4, 42, 3, 3, 42, 99, 1]
funcion(numeros)
Twisted
Twisted framework para hacer aplicaciones de red, basado en enventos, escrito en
Python y con licencia MIT.
• Twisted está formado por varios sus proyectos.
Key concepts
• Event driven
• Sin hilos
• reactor
• No bloqueante
• Deferred
• Protocolos, transports, factories y sevicios
Qué es bloqueante?
1. Python stdlib networking
2. Extensiones C
3. <adivina que va aca>
1) Python stdlib networking
• urllib[2] & httplib
• smtplib
• python-memcached
Alternativas en Twisted
• twisted.web.client
• twisted.mail.smtp
• twisted.protocols.memcache
2) Extensiones en C
• APIs de BD: psycopg2, sqlite
• Cálculo intensivo: PyCripto
• socket.gethostbyname
Alternativas en Twiseted
• twisted.enterprise.adbapi
• deferToThread
• deferToThread/twisted.names
3) Tu código
• El viejo y querido for
def procesar(datos):
for x in datos:
hacer_algo(x)
• len(datos)?
• 10
• 1000
• 1000000
• time de hacer_algo?
Reactor: multi tarea cooperativa
• Es el event loop que administra las aplicaciones que están corriendo.
• Provee interfaces básicas a disntios serivicos, incluyendo comunicaciones de red,
hilos, y disparo de eventos.
• Hay muchas implementaciones de reactor, cada una modificada para dar mejor
soporte a algunas características puntuales.
while True:
stuff = wait_for_stuff(timeout)
if stuff:
check_read_and_writes()
run_timed_events()
Reactor: distintas implementaciones
• Un reactor implementa un conjunto de interfaces. Dependiendo del elegido y la
plataforma, puede ser que algunas no estén implementadas.
• IReactorCore: funcionalidades principales (requerido)
• IReactorFDSet: usa objetos FileDescriptor
• IReactorProcess: manejo de procesos.
• IReactorSSL: soporte para SSL networking.
• IReactorTCP: soporte para TCP networking.
• IReactorThreads: administración y uso de hilos.
• IReactorTime: calendarización.
• IReactorUDP: soporte para UDP networking.
• IReactorUNIX: soporte para sockets UNIX.
Deferreds
• Una promesa de un resultado
• Pieza clave de construcción de todo el framework
• No convierten mágicamente código bloqueante en código asincrónico.
• from twisted.internet.defer import Deferred
Deferreds (addCallback)
• "Llamame cuando tengas el resulatdo."
• El que llama a una función que devuelve un Deferred puede registrar callbacks y
errbacks.
page = urlopen('http://www.python.org.ar') # bloqueante
print page.read()
d = client.getPage('http://www.python.org.ar')
def show(page):
print page
d.addCallback(show)
Deferreds (addErrback)
• "Si pasa algo avisame"
• El que llama a una función que devuelve un Deferred puede registrar callbacks y
errbacks.
try:
guardar_bloqueante(unDato) # bloqueante
except Excetion, e:
print "Algo no anduvo."
d = guardar_no_bloqueante(unDato) # retorna enseguida
def handle(error):
print "Algo no anduvo."
d.addErrback(handle)
Deferreds (errbacks y callbacks)
• El tema con los errbacks y callbacks es que vienen de a pares.
• Cuando usamos addCallback, se agrega un errback que no hace nada.
• Cuando usamos addErrback, se agrega un callback que no hace nada.
Deferreds (addCallbacks)
• Tenemos algunos métodos cómodos
d.addCallbacks(show, handle)
• Pero ojo! no es equivalente a
d.addCallback(show)
d.addErrback(handle)
Deferreds (addCallbacks)
• Si teníamos
try:
resultado = get_data_bloqueante()
resultado = procesa_datos(resultado)
except Exception, e:
resultado = maneja_excepcion(e)
• Es equivalente a
d = get_data()
d.addCallback(procesa_datos)
d.addErrback(maneja_excepcion)
Deferreds (addCallbacks)
• Pero si teníamos
try:
resultado = get_data_bloqueante()
except Exception, e:
resultado = maneja_excepcion(e)
else:
resultado = procesa_datos(resultado)
• Es equivalente a
d = get_data()
d.addCallbacks(procesa_datos, maneja_excepcion)
Deferreds
• "Tu resultado está listo"
• El que crea el deferred es responsable de llamar al callback.
• No se pueden disparar más de una vez.
• Si un deferred ya se disparó, un addCallback ejecutará directamente el callback.
class X:
def get_data(self):
self.d = Deferred()
return self.d
def data_ready(self, data)
self.d.callback(data) # solo puede ser llamado una vez!
deferToThread
• Útil, sobre todo cuando estamos empezando
• Puede no ser la solución más óptima a un problema
try:
Evento(tipo='W', texto=mensaje).save()
except:
logError()
se convierte en
d = deferToThread(Evento(tipo='W', texto=mensaje).save)
d.addErrback(logError)
Calendarizar eventos
• Ejecutar algo X segundos en el futuro
def futuro(s):
print "Se ejecutara luego de 4.1 segundos: %s" % s
reactor.callLater(4.1, futuro, "Hola, hola.")
• Si necesitamos el resultado de la ejecución:
def mostrar(resultado):
print resultado
d = task.deferLater(reactor, 4.1, futuro, "Hola, hola.")
d.addCallback(mostrar)
Calendarizar eventos
• Correr cada X segundos
from twisted.internet import task
def cadaSegundo():
print "paso 1 segundo"
l = task.LoopingCall(cadaSegundo)
l.start(1.0)
• También se pueden cancelar
call_id = reactor.callLater(5, f)
call_id.cancel()
Servidores y clientes
Escribiendo servidores
• Protocolos
• Donde implementamos el manejo y el parsing.
• twisted.internet.protocol.Protocol
• Fábricas
• Donde se guardan configuraciones persistentes.
• twisted.internet.protocol.Factory
Protocolos
• Manejan datos en forma asincrónica.
• Responde a los eventos, tan pronto como llegan por la red.
• dataReceived
from twisted.internet.protocol import Protocol
class Echo(Protocol):
def dataReceived(self, data):
self.transport.write(data)
Protocolos
• Un ejemplo respondiendo a otro evento: connectionMade
from twisted.internet.protocol import Protocol
class QOTD(Protocol):
def connectionMade(self):
self.transport.write("Al que madruga Dios lo ayuda.rn")
self.transport.loseConnection()
Protocolos
• Un ejemplo respondiendo a otro evento: connectionLost
class Echo(Protocol):
def connectionMade(self):
self.factory.numProtocols += 1
if self.factory.numProtocols > 100:
self.transport.write("Ya somos muchos.rn")
self.transport.loseConnection()
def connectionLost(self, reason):
self.factory.numProtocols -= 1
def dataReceived(self, data):
self.transport.write(data)
Protocolos basados en línea
• Basados en línea (terminan en rn o CR-LF)
• Permite un modo mixto (LineReceiver)
• o no (LineOnlyReceiver)
from twisted.protocols.basic import LineReceiver
class Answer(LineReceiver):
answers = {'Como va?': 'Bien', None : "No te entiendo"}
def lineReceived(self, line):
if self.answers.has_key(line):
self.sendLine(self.answers[line])
else:
self.sendLine(self.answers[None])
Fábricas
• Se puede extender Factory aunque por lo general no es necesario
• Asociamos un tipo de protocolo a una fábrica y conectamos la fábrica a la red
from twisted.internet.protocol import Factory
from twisted.internet import reactor
myFactory = Factory()
myFactory.protocol = Echo
reactor.listenTCP(8007, myFactory)
reactor.run()
Clientes
• Protocolos
from twisted.internet.protocol import Protocol
class Bienvenida(Protocol):
def connectionMade(self):
self.transport.write("Hola servidor, yo soy tu cliente!rn")
self.transport.loseConnection()
Fábrica de clientes
from twisted.internet.protocol import Protocol, ClientFactory
from sys import stdout
class EchoClientFactory(ClientFactory):
def startedConnecting(self, connector):
print 'Se inicio la conexion.'
def buildProtocol(self, addr):
return Echo()
def clientConnectionLost(self, connector, reason):
print 'Se perdio la conexion por:', reason
def clientConnectionFailed(self, connector, reason):
print 'Fallo la conexion por:', reason
• Reconecciones (ReconnectingClientFactory)
Qué pasa con UDP?
• Lo anterior era para TCP, SSL y sockets UNIX.
• No orientado a la conexión.
• Un socket UDP puede recibir y enviar datagramas a cualquier nodo de la red.
• Los datagramas pueden no llegar en orden, duplicarse o incluso perderse!
• No hay multiples conexiones => no necesitamos fábricas, solo un protocolo.
• Usamos el reactor para conectar el protocolo con un transport UDP
• Extendemos twisted.internet.protocol.DatagramProtocol o uno de sus
convenientes hijos.
Ejemplo UDP
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class Echo(DatagramProtocol):
def datagramReceived(self, data, (host, port)):
print "recibi %r desde %s:%d" % (data, host, port)
self.transport.write(data, (host, port))
reactor.listenUDP(9999, Echo())
reactor.run()
• ConnectedUDP
• multicast UDP
Qué no vimos?
• Conectarse a procesos locales
• http://twistedmatrix.com/documents/current/core/howto/process.html
• Distintos tipos de reactors y cómo elejirlos
• http://twistedmatrix.com/documents/current/core/howto/choosing-reactor.html
• Logging
• http://twistedmatrix.com/documents/current/core/howto/logging.html
• Sub frameworks
• Web
• Conch
• Cred
Más recursos
• http://twistedmatrix.com/documents/current/core/howto/index.html
• http://twistedmatrix.com/trac/wiki/TwistedCommunity
Créditos
• http://es.wikipedia.org/wiki/Cliente-servidor
• Cooperative Multitasking with Twisted: Getting Things Done Concurrently.
• David A Reid, 2010
• Twisted para seres humanos
• Lucio Torre, 2009
• Imágenes
• http://www.flickr.com/photos/nationalarchives/3208858799/
• http://es.wikipedia.org/wiki/Archivo:Pila-osi-es.svg
• http://es.wikipedia.org/wiki/Archivo:Winken_ueber_die_Berliner_Mauer.jpg
• http://es.wikipedia.org/wiki/Archivo:Medal_lg.jpeg
• http://www.flickr.com/photos/osucommons/3724233708/in/photostream/
Muchas gracias!
• Contacto
• mail: jjconti@gmail.com
• twitter: @jjconti
• blog: http://www.juanjoconti.com.ar
Propaganda
http://python.org.ar/pyar/CharlasAbiertas2010#Twisted
Sábado 13 de Noviembre - Charlas Abiertas de Python en La Tribu (Lambaré 873,
Capital Federal)
Twisted
Vamos a ver porque el modelo de twisted es necesario, como se programa en modo
asyncronico usando deferreds y conocer el api de red de twisted para hacer servicios.
• Disertante: Lucio Torre
• 13 a 15 horas

Más contenido relacionado

Destacado

Aplicaciones De Red Jeimy.
Aplicaciones De Red Jeimy.Aplicaciones De Red Jeimy.
Aplicaciones De Red Jeimy.Rafa Enrique
 
Unidad 2 semiotica de la imagen(publicidad).
Unidad 2 semiotica de la imagen(publicidad).Unidad 2 semiotica de la imagen(publicidad).
Unidad 2 semiotica de la imagen(publicidad).Rojo PRo
 
Proxémica y la cultra
Proxémica y la cultraProxémica y la cultra
Proxémica y la cultraOladis Farias
 
Recursos retoricos
Recursos retoricos Recursos retoricos
Recursos retoricos alexis34
 
DISEÑO DE LA ARQUITECTURA DEL SOFTWARE
DISEÑO DE LA ARQUITECTURA DEL SOFTWAREDISEÑO DE LA ARQUITECTURA DEL SOFTWARE
DISEÑO DE LA ARQUITECTURA DEL SOFTWAREjose_rob
 
Recursos retóricos
Recursos retóricosRecursos retóricos
Recursos retóricosHectorCejudo
 
La Comunicion Kinesica
La Comunicion KinesicaLa Comunicion Kinesica
La Comunicion Kinesicaedisurferx
 
Semiótica: definiciones y códigos
Semiótica: definiciones y códigosSemiótica: definiciones y códigos
Semiótica: definiciones y códigosCoppelia Yanez
 
Línea del tiempo comunicación
Línea del tiempo comunicaciónLínea del tiempo comunicación
Línea del tiempo comunicaciónjonnparis
 
Aplicaciones en la red
Aplicaciones en la redAplicaciones en la red
Aplicaciones en la redNivia Alberca
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheLeslie Samuel
 

Destacado (14)

Aplicaciones en red ppt
Aplicaciones en red pptAplicaciones en red ppt
Aplicaciones en red ppt
 
Aplicaciones De Red Jeimy.
Aplicaciones De Red Jeimy.Aplicaciones De Red Jeimy.
Aplicaciones De Red Jeimy.
 
Unidad 2 semiotica de la imagen(publicidad).
Unidad 2 semiotica de la imagen(publicidad).Unidad 2 semiotica de la imagen(publicidad).
Unidad 2 semiotica de la imagen(publicidad).
 
Proxémica y la cultra
Proxémica y la cultraProxémica y la cultra
Proxémica y la cultra
 
Subneteo redes
Subneteo redesSubneteo redes
Subneteo redes
 
Proxémica
ProxémicaProxémica
Proxémica
 
Recursos retoricos
Recursos retoricos Recursos retoricos
Recursos retoricos
 
DISEÑO DE LA ARQUITECTURA DEL SOFTWARE
DISEÑO DE LA ARQUITECTURA DEL SOFTWAREDISEÑO DE LA ARQUITECTURA DEL SOFTWARE
DISEÑO DE LA ARQUITECTURA DEL SOFTWARE
 
Recursos retóricos
Recursos retóricosRecursos retóricos
Recursos retóricos
 
La Comunicion Kinesica
La Comunicion KinesicaLa Comunicion Kinesica
La Comunicion Kinesica
 
Semiótica: definiciones y códigos
Semiótica: definiciones y códigosSemiótica: definiciones y códigos
Semiótica: definiciones y códigos
 
Línea del tiempo comunicación
Línea del tiempo comunicaciónLínea del tiempo comunicación
Línea del tiempo comunicación
 
Aplicaciones en la red
Aplicaciones en la redAplicaciones en la red
Aplicaciones en la red
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your Niche
 

Similar a Desarrollando aplicaciones de red con Twisted

Usando Twisted para hacer aplicaciones de escritorio no bloqueantes
Usando Twisted para hacer aplicaciones de escritorio no bloqueantesUsando Twisted para hacer aplicaciones de escritorio no bloqueantes
Usando Twisted para hacer aplicaciones de escritorio no bloqueantesMartín Volpe
 
Scripting para Pentesters v1.0
Scripting para Pentesters v1.0Scripting para Pentesters v1.0
Scripting para Pentesters v1.0wcuestas
 
Introducción a Celery y las colas de tareas asíncronas
Introducción a Celery y las colas de tareas asíncronasIntroducción a Celery y las colas de tareas asíncronas
Introducción a Celery y las colas de tareas asíncronasalbertoalcolea
 
Sockets y Threads en Java
Sockets y Threads en JavaSockets y Threads en Java
Sockets y Threads en JavaJose Jordan
 
Desymfony - Servicios
Desymfony  - ServiciosDesymfony  - Servicios
Desymfony - ServiciosRicard Clau
 
Reactvolution
ReactvolutionReactvolution
Reactvolution_Lagash
 
Cobertura de código con test funcionales para superhéroes
Cobertura de código con test funcionales para superhéroesCobertura de código con test funcionales para superhéroes
Cobertura de código con test funcionales para superhéroesatSistemas
 
C documents and settings_pc10_configuración local_datos de programa_mozilla_...
C  documents and settings_pc10_configuración local_datos de programa_mozilla_...C  documents and settings_pc10_configuración local_datos de programa_mozilla_...
C documents and settings_pc10_configuración local_datos de programa_mozilla_...ORLANDO LOPEZ
 
Desarrollo aplicaciones distribuidas sockets
Desarrollo aplicaciones distribuidas socketsDesarrollo aplicaciones distribuidas sockets
Desarrollo aplicaciones distribuidas socketsdandark2000
 
Aplicaciones escalables en Azure
Aplicaciones escalables en AzureAplicaciones escalables en Azure
Aplicaciones escalables en AzureGermán Küber
 
programacion concurrente java.pptx
programacion concurrente java.pptxprogramacion concurrente java.pptx
programacion concurrente java.pptxjuan gonzalez
 

Similar a Desarrollando aplicaciones de red con Twisted (20)

Usando Twisted para hacer aplicaciones de escritorio no bloqueantes
Usando Twisted para hacer aplicaciones de escritorio no bloqueantesUsando Twisted para hacer aplicaciones de escritorio no bloqueantes
Usando Twisted para hacer aplicaciones de escritorio no bloqueantes
 
Scripting para Pentesters v1.0
Scripting para Pentesters v1.0Scripting para Pentesters v1.0
Scripting para Pentesters v1.0
 
M18
M18M18
M18
 
Introducción a Celery y las colas de tareas asíncronas
Introducción a Celery y las colas de tareas asíncronasIntroducción a Celery y las colas de tareas asíncronas
Introducción a Celery y las colas de tareas asíncronas
 
Sockets y Threads en Java
Sockets y Threads en JavaSockets y Threads en Java
Sockets y Threads en Java
 
Desymfony - Servicios
Desymfony  - ServiciosDesymfony  - Servicios
Desymfony - Servicios
 
Gestión Remota de Equipos con Python
Gestión Remota de Equipos con PythonGestión Remota de Equipos con Python
Gestión Remota de Equipos con Python
 
Reactvolution
ReactvolutionReactvolution
Reactvolution
 
Cobertura de código con test funcionales para superhéroes
Cobertura de código con test funcionales para superhéroesCobertura de código con test funcionales para superhéroes
Cobertura de código con test funcionales para superhéroes
 
Rendimiento extremo en php
Rendimiento extremo en phpRendimiento extremo en php
Rendimiento extremo en php
 
C documents and settings_pc10_configuración local_datos de programa_mozilla_...
C  documents and settings_pc10_configuración local_datos de programa_mozilla_...C  documents and settings_pc10_configuración local_datos de programa_mozilla_...
C documents and settings_pc10_configuración local_datos de programa_mozilla_...
 
Desarrollo aplicaciones distribuidas sockets
Desarrollo aplicaciones distribuidas socketsDesarrollo aplicaciones distribuidas sockets
Desarrollo aplicaciones distribuidas sockets
 
Aplicaciones escalables en Azure
Aplicaciones escalables en AzureAplicaciones escalables en Azure
Aplicaciones escalables en Azure
 
PEP-3156: Async I/O en Python
PEP-3156: Async I/O en PythonPEP-3156: Async I/O en Python
PEP-3156: Async I/O en Python
 
Tema servlets
Tema servletsTema servlets
Tema servlets
 
Tema servlets
Tema servletsTema servlets
Tema servlets
 
Tema servlets
Tema servletsTema servlets
Tema servlets
 
Tema servlets
Tema servletsTema servlets
Tema servlets
 
programacion concurrente java.pptx
programacion concurrente java.pptxprogramacion concurrente java.pptx
programacion concurrente java.pptx
 
Jdbc
JdbcJdbc
Jdbc
 

Desarrollando aplicaciones de red con Twisted

  • 2. Objetivos • Mío: aprender, ordenar ideas. • Para algunos: mostrarles algo que no conocían. • Para otros: darles una razón para estudiar Python. • Esto no es un curso de Twisted, es apenas una introducción. • Si ya sabés Twisted: • No te voy a contar nada nuevo. • Tu ayuda en la charla es bienvenida!
  • 3. Agenda • Aplicaciones de red • Twisted: conceptos claves y ejemplos • Reactor • Deferreds • Servidores y clientes
  • 4. Aplicaciones de red • LAN/WAN • Internet (TCP/IP) • Cliente/Servidor
  • 6. Clientes En la arquitectura C/S el remitente de una solicitud es conocido como cliente. • Es quien inicia solicitudes o peticiones, tienen por tanto un papel activo en la comunicación (dispositivo maestro o amo). • Espera y recibe las respuestas del servidor. • Por lo general, puede conectarse a varios servidores a la vez. • Normalmente interactúa directamente con los usuarios finales mediante una interfaz gráfica de usuario.
  • 7. Servidores Al receptor de la solicitud enviada por cliente se conoce como servidor. • Al iniciarse esperan a que lleguen las solicitudes de los clientes, desempeñan entonces un papel pasivo en la comunicación (dispositivo esclavo). • Tras la recepción de una solicitud, la procesan y luego envían la respuesta al cliente. • Por lo general, aceptan conexiones desde un gran número de clientes (en ciertos casos el número máximo de peticiones puede estar limitado). • No es frecuente que interactúen directamente con los usuarios finales.
  • 8. Python • Cuantos de aca entienden esta porción de Python? def funcion(l, b=42): for x in l: if x == b: print x numeros = [1, 4, 42, 3, 3, 42, 99, 1] funcion(numeros)
  • 9. Twisted Twisted framework para hacer aplicaciones de red, basado en enventos, escrito en Python y con licencia MIT. • Twisted está formado por varios sus proyectos.
  • 10. Key concepts • Event driven • Sin hilos • reactor • No bloqueante • Deferred • Protocolos, transports, factories y sevicios
  • 11. Qué es bloqueante? 1. Python stdlib networking 2. Extensiones C 3. <adivina que va aca>
  • 12. 1) Python stdlib networking • urllib[2] & httplib • smtplib • python-memcached
  • 13. Alternativas en Twisted • twisted.web.client • twisted.mail.smtp • twisted.protocols.memcache
  • 14. 2) Extensiones en C • APIs de BD: psycopg2, sqlite • Cálculo intensivo: PyCripto • socket.gethostbyname
  • 15. Alternativas en Twiseted • twisted.enterprise.adbapi • deferToThread • deferToThread/twisted.names
  • 16. 3) Tu código • El viejo y querido for def procesar(datos): for x in datos: hacer_algo(x) • len(datos)? • 10 • 1000 • 1000000 • time de hacer_algo?
  • 17. Reactor: multi tarea cooperativa • Es el event loop que administra las aplicaciones que están corriendo. • Provee interfaces básicas a disntios serivicos, incluyendo comunicaciones de red, hilos, y disparo de eventos. • Hay muchas implementaciones de reactor, cada una modificada para dar mejor soporte a algunas características puntuales. while True: stuff = wait_for_stuff(timeout) if stuff: check_read_and_writes() run_timed_events()
  • 18. Reactor: distintas implementaciones • Un reactor implementa un conjunto de interfaces. Dependiendo del elegido y la plataforma, puede ser que algunas no estén implementadas. • IReactorCore: funcionalidades principales (requerido) • IReactorFDSet: usa objetos FileDescriptor • IReactorProcess: manejo de procesos. • IReactorSSL: soporte para SSL networking. • IReactorTCP: soporte para TCP networking. • IReactorThreads: administración y uso de hilos. • IReactorTime: calendarización. • IReactorUDP: soporte para UDP networking. • IReactorUNIX: soporte para sockets UNIX.
  • 19. Deferreds • Una promesa de un resultado • Pieza clave de construcción de todo el framework • No convierten mágicamente código bloqueante en código asincrónico. • from twisted.internet.defer import Deferred
  • 20. Deferreds (addCallback) • "Llamame cuando tengas el resulatdo." • El que llama a una función que devuelve un Deferred puede registrar callbacks y errbacks. page = urlopen('http://www.python.org.ar') # bloqueante print page.read() d = client.getPage('http://www.python.org.ar') def show(page): print page d.addCallback(show)
  • 21. Deferreds (addErrback) • "Si pasa algo avisame" • El que llama a una función que devuelve un Deferred puede registrar callbacks y errbacks. try: guardar_bloqueante(unDato) # bloqueante except Excetion, e: print "Algo no anduvo." d = guardar_no_bloqueante(unDato) # retorna enseguida def handle(error): print "Algo no anduvo." d.addErrback(handle)
  • 22. Deferreds (errbacks y callbacks) • El tema con los errbacks y callbacks es que vienen de a pares. • Cuando usamos addCallback, se agrega un errback que no hace nada. • Cuando usamos addErrback, se agrega un callback que no hace nada.
  • 23. Deferreds (addCallbacks) • Tenemos algunos métodos cómodos d.addCallbacks(show, handle) • Pero ojo! no es equivalente a d.addCallback(show) d.addErrback(handle)
  • 24. Deferreds (addCallbacks) • Si teníamos try: resultado = get_data_bloqueante() resultado = procesa_datos(resultado) except Exception, e: resultado = maneja_excepcion(e) • Es equivalente a d = get_data() d.addCallback(procesa_datos) d.addErrback(maneja_excepcion)
  • 25. Deferreds (addCallbacks) • Pero si teníamos try: resultado = get_data_bloqueante() except Exception, e: resultado = maneja_excepcion(e) else: resultado = procesa_datos(resultado) • Es equivalente a d = get_data() d.addCallbacks(procesa_datos, maneja_excepcion)
  • 26. Deferreds • "Tu resultado está listo" • El que crea el deferred es responsable de llamar al callback. • No se pueden disparar más de una vez. • Si un deferred ya se disparó, un addCallback ejecutará directamente el callback. class X: def get_data(self): self.d = Deferred() return self.d def data_ready(self, data) self.d.callback(data) # solo puede ser llamado una vez!
  • 27. deferToThread • Útil, sobre todo cuando estamos empezando • Puede no ser la solución más óptima a un problema try: Evento(tipo='W', texto=mensaje).save() except: logError() se convierte en d = deferToThread(Evento(tipo='W', texto=mensaje).save) d.addErrback(logError)
  • 28. Calendarizar eventos • Ejecutar algo X segundos en el futuro def futuro(s): print "Se ejecutara luego de 4.1 segundos: %s" % s reactor.callLater(4.1, futuro, "Hola, hola.") • Si necesitamos el resultado de la ejecución: def mostrar(resultado): print resultado d = task.deferLater(reactor, 4.1, futuro, "Hola, hola.") d.addCallback(mostrar)
  • 29. Calendarizar eventos • Correr cada X segundos from twisted.internet import task def cadaSegundo(): print "paso 1 segundo" l = task.LoopingCall(cadaSegundo) l.start(1.0) • También se pueden cancelar call_id = reactor.callLater(5, f) call_id.cancel()
  • 31. Escribiendo servidores • Protocolos • Donde implementamos el manejo y el parsing. • twisted.internet.protocol.Protocol • Fábricas • Donde se guardan configuraciones persistentes. • twisted.internet.protocol.Factory
  • 32. Protocolos • Manejan datos en forma asincrónica. • Responde a los eventos, tan pronto como llegan por la red. • dataReceived from twisted.internet.protocol import Protocol class Echo(Protocol): def dataReceived(self, data): self.transport.write(data)
  • 33. Protocolos • Un ejemplo respondiendo a otro evento: connectionMade from twisted.internet.protocol import Protocol class QOTD(Protocol): def connectionMade(self): self.transport.write("Al que madruga Dios lo ayuda.rn") self.transport.loseConnection()
  • 34. Protocolos • Un ejemplo respondiendo a otro evento: connectionLost class Echo(Protocol): def connectionMade(self): self.factory.numProtocols += 1 if self.factory.numProtocols > 100: self.transport.write("Ya somos muchos.rn") self.transport.loseConnection() def connectionLost(self, reason): self.factory.numProtocols -= 1 def dataReceived(self, data): self.transport.write(data)
  • 35. Protocolos basados en línea • Basados en línea (terminan en rn o CR-LF) • Permite un modo mixto (LineReceiver) • o no (LineOnlyReceiver) from twisted.protocols.basic import LineReceiver class Answer(LineReceiver): answers = {'Como va?': 'Bien', None : "No te entiendo"} def lineReceived(self, line): if self.answers.has_key(line): self.sendLine(self.answers[line]) else: self.sendLine(self.answers[None])
  • 36. Fábricas • Se puede extender Factory aunque por lo general no es necesario • Asociamos un tipo de protocolo a una fábrica y conectamos la fábrica a la red from twisted.internet.protocol import Factory from twisted.internet import reactor myFactory = Factory() myFactory.protocol = Echo reactor.listenTCP(8007, myFactory) reactor.run()
  • 37. Clientes • Protocolos from twisted.internet.protocol import Protocol class Bienvenida(Protocol): def connectionMade(self): self.transport.write("Hola servidor, yo soy tu cliente!rn") self.transport.loseConnection()
  • 38. Fábrica de clientes from twisted.internet.protocol import Protocol, ClientFactory from sys import stdout class EchoClientFactory(ClientFactory): def startedConnecting(self, connector): print 'Se inicio la conexion.' def buildProtocol(self, addr): return Echo() def clientConnectionLost(self, connector, reason): print 'Se perdio la conexion por:', reason def clientConnectionFailed(self, connector, reason): print 'Fallo la conexion por:', reason • Reconecciones (ReconnectingClientFactory)
  • 39. Qué pasa con UDP? • Lo anterior era para TCP, SSL y sockets UNIX. • No orientado a la conexión. • Un socket UDP puede recibir y enviar datagramas a cualquier nodo de la red. • Los datagramas pueden no llegar en orden, duplicarse o incluso perderse! • No hay multiples conexiones => no necesitamos fábricas, solo un protocolo. • Usamos el reactor para conectar el protocolo con un transport UDP • Extendemos twisted.internet.protocol.DatagramProtocol o uno de sus convenientes hijos.
  • 40. Ejemplo UDP from twisted.internet.protocol import DatagramProtocol from twisted.internet import reactor class Echo(DatagramProtocol): def datagramReceived(self, data, (host, port)): print "recibi %r desde %s:%d" % (data, host, port) self.transport.write(data, (host, port)) reactor.listenUDP(9999, Echo()) reactor.run() • ConnectedUDP • multicast UDP
  • 41. Qué no vimos? • Conectarse a procesos locales • http://twistedmatrix.com/documents/current/core/howto/process.html • Distintos tipos de reactors y cómo elejirlos • http://twistedmatrix.com/documents/current/core/howto/choosing-reactor.html • Logging • http://twistedmatrix.com/documents/current/core/howto/logging.html • Sub frameworks • Web • Conch • Cred
  • 43. Créditos • http://es.wikipedia.org/wiki/Cliente-servidor • Cooperative Multitasking with Twisted: Getting Things Done Concurrently. • David A Reid, 2010 • Twisted para seres humanos • Lucio Torre, 2009 • Imágenes • http://www.flickr.com/photos/nationalarchives/3208858799/ • http://es.wikipedia.org/wiki/Archivo:Pila-osi-es.svg • http://es.wikipedia.org/wiki/Archivo:Winken_ueber_die_Berliner_Mauer.jpg • http://es.wikipedia.org/wiki/Archivo:Medal_lg.jpeg • http://www.flickr.com/photos/osucommons/3724233708/in/photostream/
  • 44. Muchas gracias! • Contacto • mail: jjconti@gmail.com • twitter: @jjconti • blog: http://www.juanjoconti.com.ar
  • 45. Propaganda http://python.org.ar/pyar/CharlasAbiertas2010#Twisted Sábado 13 de Noviembre - Charlas Abiertas de Python en La Tribu (Lambaré 873, Capital Federal) Twisted Vamos a ver porque el modelo de twisted es necesario, como se programa en modo asyncronico usando deferreds y conocer el api de red de twisted para hacer servicios. • Disertante: Lucio Torre • 13 a 15 horas