48

Acabo de comenzar a jugar con arquitecturas basadas en eventos, provenientes de una mentalidad orientada a objetos bastante estándar.Escribiendo el código manejado por eventos que se puede mantener

La primera cosa que noté fue que la dificultad en la comprensión y el seguimiento a través de programas parece aumentar exponencialmente con el tamaño del programa. Si bien los proyectos de mascotas pequeñas son fáciles de seguir, parece que el código rápidamente se convertirá en espagueti.

entiendo que soy nuevo en este modo de pensar el desarrollo y no todas mis preocupaciones orientadas a objetos a través. ¿Hay algún recurso para escribir código entendible manejado por eventos? ¿Qué hacen las personas que usan node.js o Twisted o Event Machine sobre esto?

Respuesta

4

Voy a usar Python como un ejemplo ya que es lo que estoy utilizando para construir aplicaciones distribuidas enormes en este momento.

pitón Twisted permite un estilo muy imprescindible el uso de cualquiera de inlinecallbacks o estilos deferredGenerator (un poco más feas). Estos métodos le permiten escribir procedimientos que usan un código de devolución de llamada impulsado por eventos que es mucho más fácil de leer y comprender. La implementación convierte su función en una secuencia perezosa que produce una secuencia de diferidos.

Específicamente, no tiene que crear un conjunto de funciones de devolución de llamada/lambdas/closures profundamente anidados, y en su lugar puede ceder el control de una función al bucle de evento en puntos arbitrarios. Puede volver a etiquetar mentalmente esto como corrutinas o multitarea cooperativa si lo desea. Hace el trabajo. Un ejemplo sería (usando el estilo deferredGenerator más feo) como esto:

@defer.deferredGenerator 
def foo(arg): 
    bar = nonBlockingFunction(foo) 
    baz = waitForDeferred(aFunctionThatReturnsADeferredToo(bar)) 
    yield baz #Returns control to the event loop 
    output = baz.getResult() #This gets the output of aFunctionThat...Too above 
    yield output #This is how we return a result instead of using return 

@defer.deferredGenerator 
def aFunctionThatReturnsADeferredToo(put_bar_here): 
    """Stuff happens here....""" 
    ...etc... 

Hay otro post aquí que muestra el método inlineCallbacks, que es más limpio, pero requiere Python 2.5 o más reciente (es decir, no bajo Centos/RHEL 5 serie, que estoy tristemente atrapado con mi aplicación). Si puedes usarlo, hazlo.

Como puede ver, esto se parece a las cosas imperativas de python de la vieja escuela que conoce y ama, pero que es MUCHO más fácil de mantener sin una gran cantidad de funciones anidadas y lambdas. Aun así, me gustaría que Python tuviera bloques.

En cuanto a la depuración, puede activar la depuración de reactor retorcido mediante la llamada defer.setDebugging (True) en algún lugar de su código de inicialización. Esto adjuntará el rastreo original que generó una excepción en su código, de modo que pueda ver trivialmente dónde se produjo el error REALMENTE. Solo recuerde redactar la sentencia setDebugging antes de comenzar la producción, ya que resulta en una GRAN cantidad de introspección adicional (mire en voz alta si quiere estar completamente horrorizado).

1

Obviamente existen ya las mejores prácticas y modelos que continuarán desarrollándose con el tiempo.

Sin embargo, tenga en cuenta también la posibilidad de que evented programación ofrece la oportunidad de "pequeños proyectos favoritos" para interactuar entre sí. Imagine un mundo donde miles de proyectos individuales distribuidos interactuaban en tiempo real a través de devoluciones de llamada definidas por el usuario.

Usuarios y desarrolladores serían capaces de volver a colocar la web y aplicaciones a través de los protocolos existentes desde la parte superior hacia abajo en vez de confiar en el diseño de aplicaciones existentes. Los diseñadores de aplicaciones serían entonces libres de enfocarse en casos de uso individual en lugar de proporcionar soluciones uniformes o preocuparse por todas las contingencias posibles.

Salida Web Hooks y mirar cómo los servicios como Twilio ya están operando

4

Para Twisted, en lugar de usar el antiguo generador diferido, recomiendo inlineCallbacks; Le permite escribir completamente el código de estilo de bloqueo y seguir jugando muy bien con el ciclo de eventos.

@defer.inlineCallbacks 
def foo(arg): 
    bar = nonBlockingFunction(foo) 
    output = yield FunctionThatReturnsADeferredToo(bar) 
    defer.returnValue(output) #This is how we return a result instead of using return 
6

Martyn Loughran wrote an excellent short article por completo acerca de cómo evitar los espaguetis de devolución de llamada.

Lo que realmente disfruté de su artículo es el proceso de mejorar los espaguetis en algo agradable y limpio; puede parecer un poco formalizado al principio, pero cuando veas el resultado final, creo que estarás de acuerdo en que muestra una maestría real en un código limpio y legible.

1

Mi único consejo es think functional.

+2

cuidado para elaborar? – keyle

Cuestiones relacionadas