2012-02-03 11 views
10

Tengo una aplicación de servicio C# que interactúa con una base de datos. Recientemente se migró de .NET 2.0 a .NET 4.0, por lo que hay muchas herramientas nuevas que podríamos usar.Qué herramientas de C# existen para desencadenar, poner en cola, priorizar tareas dependientes

Busco punteros a métodos de programación o herramientas/librerías para manejar la definición de tareas, las tareas de configuración de los que dependen, haciendo cola, dando prioridad, cancelación, etc.

Hay varios tipos de servicios:

  • datos (para recuperar y actualizar)
  • cálculo (poblar alguna tabla con los resultados de un cálculo sobre los datos)
  • informes

Estos servicios a menudo dependen el uno del otro y se activan en la demanda, es decir, un informes tarea, probablemente tendrá código dentro de él, como

if (IsSomeDependentCalculationRequired()) 
    PerformDependentCalculation(); // which may trigger further calculations 
GenerateRequestedReport(); 

Además, cualquier Datos modificación es probable que establezca el Required indicador en algunos de los Cálculo o Informes servicios, (por lo que el informe podría estar desactualizado antes de que termine de generar). Las tareas varían en duración de algunos segundos a un par de minutos y se realizan dentro de las transacciones.

Esto ha funcionado bien hasta ahora, pero no está escalando bien. Hay problemas de diseño fundamentales y estoy buscando reescribir esta parte del código. Por ejemplo, si dos usuarios solicitan el mismo informe en momentos similares, las tareas dependientes se ejecutarán dos veces. Además, actualmente no hay forma de cancelar una tarea en progreso. Es difícil mantener las tareas dependientes, etc.

No estoy buscando sugerencias sobre cómo implementar una solución. Más bien, estoy buscando indicadores sobre qué herramientas/bibliotecas utilizaría para este tipo de requisitos si comenzara en .NET 4 desde cero. ¿Sería este un buen candidato para Windows Workflow? ¿Es esto para lo que es Futures? ¿Hay alguna otra biblioteca que deba ver o libros o publicaciones de blog que deba leer?

Editar: ¿Qué hay de Rx Reactive Extensions?

+1

Basado en una demostración que vi de Workflow, parece una buena combinación para sus requisitos, pero como en realidad no lo he usado, lo estoy ofreciendo como un comentario y no como una respuesta ... para qué merece la pena. –

+0

Probablemente sea útil si puede comentar un poco más las respuestas individuales. De esa forma podemos elaborar en la dirección correcta. – usr

+0

¿Qué pasa con [Extensiones reactivas de Rx] (http://msdn.microsoft.com/en-us/data/gg577609)? ¿Es ese el mejor enfoque para mis requerimientos? – shamp00

Respuesta

4

No creo que sus requisitos quepan en ninguna de las cosas incorporadas. Sus requisitos son demasiado específicos para eso.

Recomiendo que cree una infraestructura de puesta en cola de tareas alrededor de una base de datos SQL. Sus tareas son bastante largas (segundos) por lo que no necesita un alto rendimiento en el programador de tareas. Esto significa que no encontrará obstáculos de rendimiento.En realidad, será una tarea bastante manejable desde una perspectiva de programación.

Probablemente debe construir un servicio de Windows o algún otro proceso que esté continuamente sondeando la base de datos para nuevas tareas o solicitudes. Este servicio puede entonces hacer cumplir reglas arbitrarias en las tareas solicitadas. Por ejemplo, puede detectar que una tarea de informes ya se está ejecutando y no programar un nuevo cálculo.

Mi punto principal es que sus requisitos son tan específicos que debe usar el código C# para codificarlos. No puede hacer que una herramienta existente se ajuste a sus necesidades. Necesita la integridad completa de un lenguaje de programación para hacerlo usted mismo.

Editar: Probablemente deba separar una solicitud de tarea de una ejecución de tarea. Esto permite que varias partes soliciten una actualización de algunos informes mientras que, al mismo tiempo, solo se está ejecutando un cálculo real. Una vez que se completa este cálculo, todas las solicitudes de tareas se marcan como completadas. Cuando se cancela una solicitud, la ejecución no necesita ser cancelada. Solo cuando se cancela la última solicitud , también se cancela la ejecución de la tarea.

Edición 2: No creo que los flujos de trabajo sean la solución. Los flujos de trabajo generalmente operan por separado el uno del otro. Pero tú no quieres eso. Desea tener reglas que abarquen múltiples tareas/flujos de trabajo. Usted estaría trabajando contra el sistema con un modelo basado en flujo de trabajo.

Edición 3: Algunas palabras sobre el TPL (Task Parallel Library). Usted lo mencionó ("Futuros"). Si desea obtener inspiración sobre cómo las tareas pueden funcionar juntas, cómo se pueden crear las dependencias y cómo se pueden componer las tareas, consulte la Biblioteca de tareas paralelas (en particular las clases Task y TaskFactory). Encontrará algunos buenos patrones de diseño allí porque está muy bien diseñado. A continuación se explica cómo modela una secuencia de tareas: llama a Task.ContinueWith que registrará una función de continuación como una nueva tarea. Así es como modela las dependencias: TaskFactory.WhenAll (Task []) inicia una tarea que solo se ejecuta cuando se completan todas sus tareas de entrada.

PERO: El TPL en sí mismo probablemente no sea adecuado para usted porque su tarea no se puede guardar en el disco. Cuando reinicia su servidor o implementa un nuevo código, todas las tareas existentes se cancelan y el proceso se cancela. Esto es probable que sea inaceptable. Usa el TPL como inspiración. Aprende de lo que es una "tarea/futuro" y cómo pueden ser compuestos. Luego implemente su propia forma de tareas.

¿Le sirve de ayuda?

+0

Agregué muchas cosas y dije algunas cosas sobre futuros. – usr

+1

Gracias muy útiles. Probablemente habría perdido mucho tiempo mirando a WF sin su comentario, y miraré la Biblioteca de tareas paralelas como sugiera. – shamp00

+1

Aunque todavía no estoy seguro exactamente qué enfoque utilizar, esta fue la respuesta más útil y merece la recompensa. He jugado con varias de las sugerencias y me estoy inclinando hacia TPL o Rx. – shamp00

3

Si desea resolver este problema fundamental correctamente y de una manera escalable, probablemente debería tener el estilo de arquitectura SOA. Tus servicios recibirán comandos y generarán eventos que puedes manejar para reaccionar ante los hechos que suceden en tu sistema.

Y, sí, hay herramientas para ello. Por ejemplo, NServiceBus es una herramienta maravillosa para construir sistemas SOA.

+1

¿De qué manera NServiceBus ayuda con cola/desencadenar/priorizar tareas dependientes ?. No estoy buscando cómo definir un servicio: la aplicación ya tiene una arquitectura orinada por el servicio (usando [RemObjects] (http://www.remobjects.com/ro/)).Estoy buscando cómo definir cómo diferentes servicios dependen uno del otro y ejecutar múltiples solicitudes de manera óptima. – shamp00

+1

NServiceBus no ayuda con las tareas de priorización/activación. SOA lo hace. Y NServiceBus es una buena plataforma para construir SOA en la parte superior. En SOA los servicios no se comunican entre sí y definitivamente no tienen dependencias que no se conozcan entre sí. Publican eventos en los que otros servicios pueden (o no) suscribirse. Y su ejemplo de generación de informes probablemente parezca una saga que podría desencadenarse por algunos eventos y podría gestionar dicho proceso. –

+2

Esta respuesta no ayuda con los requisitos. No veo cómo SOA apoya la noción de tareas. SOA tiene diferentes objetivos arquitectónicos que el OP tiene. Además, los servicios web son un mecanismo RPC. No resuelven un problema particular aparte de eso. – usr

4

Intentaré utilizar el paquete de máquina de estado stateless para modelar el flujo de trabajo. El uso de un paquete proporcionará una forma consistente de avanzar en el estado del flujo de trabajo a través de los diversos servicios. Cada uno de sus servicios tendrá una implementación interna de máquina de estado y expondrá métodos para avanzar. Stateless será responsable de desencadenar acciones basadas en el estado del flujo de trabajo y le exigirá configurar explícitamente los distintos estados en los que puede estar; esto será especialmente útil para el mantenimiento y probablemente lo ayude a comprender mejor el dominio.

+0

Una gran sugerencia: el tipo de cosa que esperaba. Lo echaré un vistazo. – shamp00

1

Puede hacer un agente de datos SQL para ejecutar consultas SQL en intervalos temporizados. Tienes que escribir la aplicación tú mismo. Escribe como un programa de larga ejecución que comprueba el tiempo y hace algo. No creo que haya herramientas claras para hacer lo que intentas hacer. Haga la aplicación C#, servicio WCF. la automatización de datos se puede hacer en el sql mismo.

1

Si entiendo bien, quiere almacenar en caché los informes generados y no volver a trabajar. Como otros comentaristas han señalado, esto se puede resolver elegantemente con múltiples colas Producer/Consumer y algunos caches. Primero encola tu solicitud de informe.En función de los parámetros de generación de informes, puede verificar primero la memoria caché si ya está disponible un informe generado previamente y simplemente devolver este. Si debido a cambios en la base de datos, el informe se vuelve obsoleto, debe tener cuidado de que la memoria caché se invalide de manera confiable.

Ahora, si aún no se generó el informe, necesita programar el informe para la generación. El planificador de informes necesita comprobar si el mismo informe ya se está generando. En caso afirmativo, registre un evento para notificarlo cuando se complete y devuelva el informe una vez que haya finalizado. Asegúrese de no acceder a los datos a través de la capa de almacenamiento en caché, ya que podría generar carreras (se genera un informe, se cambian los datos y el informe final se desclasificará inmediatamente por el caché, dejando que anote su regreso).

O si desea evitar la devolución de informes obsoletos, puede dejar que la capa de almacenamiento en caché se convierta en su principal proveedor de datos, lo que generará tantos informes hasta que se genere un informe a tiempo que no esté desactualizado. Pero tenga en cuenta que si tiene constantes cambios en su base de datos, puede ingresar aquí un bucle sin fin al generar constantemente informes no válidos si el tiempo de generación de informes es más largo que el tiempo promedio entre cambios en su base de datos.

Como puede ver, tiene muchas opciones aquí sin hablar realmente de .NET, TPL, servidor SQL. En primer lugar, debe establecer sus metas con la rapidez/escalabilidad y confiabilidad que debe tener su sistema, luego debe elegir el diseño de arquitectura apropiado como se describió anteriormente para su dominio problemático en particular. No puedo hacerlo por ti porque no tengo tu dominio completo para saber qué es aceptable y qué no.

La parte engañosa es la parte de traspaso entre diferentes colas con las garantías de fiabilidad y corrección adecuadas. Dependiendo de las necesidades específicas de generación de informes, puede poner esta lógica en la nube o usar un solo hilo al poner todo el trabajo en las colas adecuadas y trabajar en ellas al mismo tiempo o una por una o algo intermedio.

TPL y el servidor SQL pueden ayudar con seguridad pero son solo herramientas. Si se usa incorrectamente debido a la falta de experiencia con uno u otro, podría resultar que un enfoque diferente (como el uso de solo en colas de memoria e informes persistentes en el sistema de archivos) sea más adecuado para su problema.

Desde mi comprensión actual no utilizaría el servidor SQL a un mal uso como memoria caché, pero si quieres una base de datos que podría utilizar algo como RavenDB o RaportDB que miran peso estable y mucho más ligero en comparación con un servidor SQL completo soplado.

Pero si ya tiene un servidor SQL ejecutándose, siga adelante y úselo.

0

No estoy seguro si entendí bien, pero es posible que desee echar un vistazo a JAMS Scheduler: http://www.jamsscheduler.com/. No es gratis, pero es un sistema muy bueno para programar tareas dependientes y generar informes. Lo he usado con éxito en mi empresa anterior. Está escrito en .NET y tiene una API .NET para que pueda escribir sus propias aplicaciones comunicándose con JAMS. También tienen un muy buen soporte y están ansiosos por implementar nuevas características.

Cuestiones relacionadas