Pregunta

Tengo una instancia de flujo de trabajo de Windows que utiliza la persistencia de SQL, que se hospeda en el tiempo de ejecución de la web, ya que los flujos de trabajo se inician mediante los formularios de ASP.NET. Funciona muy bien la mayor parte del tiempo, pero he notado casos en los que tengo que patear cosas:

Noto que el siguiente temporizador se ha retrasado mucho, incluso por horas. A veces, los campos ownerID y ownUntil son nulos en la base de datos de persistencia, a veces no. El " desbloqueado " y " bloqueado " los campos son siempre ambos "1".

... y luego el tiempo de ejecución del flujo de trabajo no lo recupera hasta que anule el " propietario " campos si están poblados y patea el grupo de aplicaciones con un reciclaje, y las cosas van muy bien después de eso en su mayor parte. No hay errores (tengo bloques try / catch alrededor de todo y escribo cualquier cosa atrapada en un archivo de rastreo), así que no es eso.

Las actividades de retardo que causan la persistencia están configuradas en un minuto, y la duración de propiedad para el tiempo de ejecución también es de 60 segundos. El código en el que se atasca siempre debería tomar menos de un minuto.

Mientras escribo esto, tengo curiosidad por saber si los reciclajes del grupo de aplicaciones / dominio de aplicaciones lo están causando ... cuando el flujo de trabajo intenta llamar a cualquier método en el tiempo de ejecución, está ocupado activando el dominio / grupo de aplicaciones y podría fugas durante los 60 segundos de duración de la propiedad. ¿Eso suena remotamente plausible, y eso causaría que no se rehidrate adecuadamente?

Salvo ese desvío, ¿qué podría causar este comportamiento que estoy viendo? No quiero cuidar el tiempo de ejecución todos los días despegando los flujos de trabajo atascados.

¿Fue útil?

Solución

Es muy probable que el reciclaje del dominio de la aplicación sea una gran parte de su problema. IIS reciclará un dominio de aplicación tan pronto como finalice la última solicitud. Sin embargo, no ve el código que se ejecuta en otro hilo como parte de esa solicitud. Esa es una de las razones principales por las que se usa ManualWorkflowSchedulerService cuando se hospeda en IIS. Pero cuando usa la opción de temporizadores activos, todavía usa un hilo de fondo para ejecutar actividades de flujo de trabajo.

También asegúrese de descargar los flujos de trabajo tan pronto como estén inactivos. La forma más fácil de hacerlo es usar la configuración UnloadOnIdle en SqlWorkflowPersistenceService.

El PersistenceService busca flujos de trabajo con una propiedad vencida pero solo en el momento del inicio. Por lo tanto, lo más probable es que al reiniciar el proceso de trabajo de IIS también se reinicien los flujos de trabajo antiguos sin ningún trabajo adicional. Pero ya que este es el caso de nuevos problemas ... Solo eliminar el antiguo propietario también debería hacer el truco. En ese caso, PersistenceService debería recargar los flujos de trabajo la próxima vez. El único truco es saber qué ID de runitme es antiguo y cuál no (la propiedad que contiene el valor no es pública).

Otra cosa de la que hay que asegurarse es que el proceso de trabajo de IIS se vuelve a cargar. Si esto no se hace, no hay tiempo de ejecución de WF, por lo que no puede verificar los temporizadores caducados. Parece que tienes esto cubierto, pero por si acaso.

Otros consejos

Las instancias de flujo de trabajo están bloqueadas en un tiempo de ejecución (por lo que múltiples tiempos de ejecución de flujo de trabajo pueden compartir una base de datos sin que ambas manejen las instancias). Cuando AppDomain se recicla, se debe detener el tiempo de ejecución, haciendo que las instancias se desbloqueen

Esto podría ser redundante, no lo comprobé, pero ayudó a desbloquear las instancias de flujo de trabajo:

AppDomain.CurrentDomain.DomainUnload += ((sender, args) =>
                                             {
                                                 if (_runtime.IsStarted)
                                                     _runtime.StopRuntime();
                                             });
AppDomain.CurrentDomain.ProcessExit += ((sender, args) =>
                                            {
                                                if (_runtime.IsStarted)
                                                    _runtime.StopRuntime();
                                            });

¿Ha revisado el reloj en su db y servidores web (si no son el mismo servidor)? He tenido problemas similares antes con el flujo de trabajo y la causa principal fue que los relojes de la base de datos y el servidor web no estaban sincronizados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top