2012-05-15 12 views
8

actualización

Debería haber añadido desde el principio - esto es en Microsoft Dynamics CRM¿Por qué se activa la protección infinita de bucle en mi flujo de trabajo de CRM?


conozco bien CRM, pero estoy en una pérdida para explicar el comportamiento de mi despliegue actual .

Lea el bosquejo de mi escenario para ayudarme a entender cuál de mis presunciones/interpretaciones es incorrecta (y, por lo tanto, cuál es la causa de este error). No es consistente con mis expectativas.

básico Escenario

  • requisito que exige un servicio web se llama cada X minutos (que se suma a la espera de artículos a un índice de base de datos)
  • He optado por utilizar una entidad de flujo de trabajo/personalizada modelo desencadenante (es decir, tengo una entidad personalizada que tiene un complemento CREATE registrado. El complemento ejecuta mi lógica. Un flujo de trabajo acompañante se inicia cuando tiempo "completado" + [período de tiempo de espera] expira. Al expirar, crea un nuevo registro desencadenante y el flujo de trabajo termina).
  • La lógica del complemento funciona bien. El concepto de flujo de trabajo funciona bien hasta cierto punto, pero después de un período de tiempo el flujo de trabajo se detiene con un error:

    Este trabajo de flujo de trabajo se canceló porque el flujo de trabajo que lo inició incluía un ciclo infinito. Corrija la lógica del flujo de trabajo y vuelva a intentarlo. Para obtener información sobre la lógica del flujo de trabajo, consulte la Ayuda.

En pocas palabras, detección de bucle infinito estándar. Entiendo el concepto y por qué existe.

despliegue específico

En primer lugar, creo que es bastante seguro para nosotros ignorar el contenido del código del plugin en este escenario. Funciona bien, es atómico y apenas toca CRM (para ser claros, es un plugin previo al evento que ejecuta el servicio web remoto, espera una respuesta y luego establece el atributo de fecha/hora "completado" en mi registro de activación antes de pasar la entidad objetivo de nuevo en la tubería). Siempre que se cree un registro de Disparo, este código se ejecuta y hace lo que debería.

Después de haber descontado el contenido del plugin, puede haber un problema que no me gusta en tener el plugin registrado en el pre-crear el paso de la entidad ...

Así que deja el flujo de trabajo propio . Es simple. Se ejecuta así:

  1. En la creación de una nueva entidad de disparo ...
  2. que tiene un tiempo de espera de 15 minutos + Trigger.new_completedon
  3. el tiempo de espera, se crea un nuevo registro de activación (sin " completado en "valor: esto lo establece el complemento recordar)
  4. Eso es todo, no hay un" flujo de trabajo final "explícito (aunque acabo de agregar uno ahora y lo estableceré para probar ...)

Con esta configuración, creo manualmente un nuevo registro de Disparo y el proceso se activa muy bien. Avanzar 1h 58 mins (basado en el último ciclo que ejecuté, recordando que mi código de complemento puede tardar un minuto en ejecutarse), después de 7 ciclos de ejecución exitosos (es decir, nuevos trabajos de flujo de trabajo creados y completados), el 8º falla con el el error mencionado anteriormente.

lo que ya sé (corregirme cuando me equivoco)

Recursion depth, by default, is set to 8. Si un flujo de trabajo/complemento se llama a sí mismo 8 veces, se detecta un ciclo infinito.

Recursion depth is reset every one hour (or 10 minutes - see "Warnings" in linked blog?)

Recursion depth settings can be set via PowerShell o código SDK utilizando el Deployment Web Serviceen una implementación local solamente (via the Set-CrmSetting Cmdlet)

lo que no quiere oír (por favor)

"Cambiar la configuración de profundidad de recursión"

No puedo cambiar la configuración de Profundidad de recursión de implementación, ya que no es una opción en un escenario en línea; en última instancia, también implementaré en CRM Online.

"Aumentar el tiempo de espera en su flujo de trabajo"

Esta no es una opción, ya sea - el reindex tiene que ocurrir cada 15 minutos, a ser posible antes.

actualización

@Boone sugiere a continuación que el tiempo de espera de nivel de recursividad se restablece después de 60 minutos de inactividad en vez de cada 60 minutos. Ahí radica el primer malentendido.

Al hablar con @alex, sugerí que puede haber cierta persistencia de CorrelationId entre crear una entidad a través del flujo de trabajo y el flujo de trabajo que se genera finalmente ... Bueno, sí existe. El Id. De correlación es el mismo tanto en el complemento como en el flujo de trabajo y cualquier registro que se encargue de ese subproceso. Ahora estoy buscando formas de desacoplar la CorrelationId (o tal vez la creación de registros) de la entidad y el flujo de trabajo.

+0

El flujo de trabajo se está llamando a sí mismo, es por eso que termina en un ciclo infinito. Tendrá que replantearse todo el enfoque, aumentar la profundidad o el tiempo de espera solo retrasaría la eliminación del proceso debido a un bucle infinito. – Alex

+0

Gracias por su respuesta Alex - lo ha hecho sonar simple, pero no creo que sea así. Incluso si aceptamos que el flujo de trabajo se está llamando a sí mismo (MSCRM cree que sí, creo que no es así), el flujo de trabajo crea un nuevo registro, en lugar de volver a llamarse explícitamente como flujo de trabajo secundario. Esperaría que fuera un nuevo ". hilo "- aunque quizás el Id. de correlación del complemento herede del padre y pase a los flujos de trabajo secundarios posteriores), la profundidad de la recursión debe reiniciarse cada 10 o 60 minutos, pero no es así. –

+0

Creo que MSCRM realmente reconoce que la recursión indirecta tiene lugar allí debido exactamente a los Índices de Correlación, por eso la detección de bucles entra en acción. Estoy intrigado, experimentaré un poco y me pondré en contacto contigo (esto también podría ser útil para mí, ¿quién sabe si/cuándo recibiré un requisito similar? (:) – Alex

Respuesta

2

Para que tenga lugar el "reinicio" de una hora, no debe haber actividad durante una hora. No se restablece solo 1 hora desde el original. Entonces, como tiene una actividad cada 15 minutos, nunca tiene la posibilidad de reiniciar. No sé lo que se dice en piedra en cualquier lugar ... pero según mi experiencia.

En CRM 4 fue posible crear un Servicio CRM (Google creating a CRM service in the child pipeline) y restablecer la ID de correlación (utilizando CorrelationToken.NewToken()). No veo nada tan fácil en el SDK 2011. No tengo idea de si este truco funcionó en el entorno en línea. ¿Es el 2011 en línea compatible con los complementos de CRM 4?

Una cosa que podría intentar sería usar el IExecutionContext.CorrelationId para eliminar la tabla de asycoperation (trabajo del sistema). Pero de acuerdo con los metadatos, el atributo que creo que podría ser útil (CorrelationId, CorrelationUpdatedTime, Depth) NO son válidos para la actualización. ¿Tal vez podría eliminar las filas? Incluso eso puede no ayudar.

+0

Gracias Boone.No había considerado la "hora", es decir, 60 minutos de inactividad, y todavía lucho por leer el SDK para decirlo, pero me interesa escuchar que esta es su experiencia (¡no sorprende si los documentos son inexactos ...!). Consideré muy brevemente hacer algo con CorrelationId, sin ir por la ruta completa de registrarlo y verificarlo como la causa (lo cual haré ahora siguiendo los comentarios de Alex anteriores) pero noté que solo tiene un getter, por lo que no puede actualizarse. No creo que los complementos de v4 sean válidos para CRM Online, por lo que el truco de servicio de CRm tampoco será viable, me temo. –

+0

Sí, puede ser difícil de lograr en los complementos de arena. No creo que puedas usar el reflejo (que podría usarse para llegar al miembro/instalador privado). En el entorno en línea, puede estar limitado a un servicio externo. Incluso si fue capaz de hacer que funcione el código de Alex, no desea configurar CorrelationId en el contexto anterior, quiere usar un Id nuevo (ese es el punto). –

+0

Bien pensado pregunta por cierto. Aquí espero no tener que actualizar mis plug-ins de CRM 4 que cambian la correlación en el entorno en línea de arena :) –

2

Dudo que esto se pueda resolver de esta manera.

Sugeriría un enfoque diferente: implementar una aplicación simple junto con CRM y dejar que sea llamar al servicio web, que a su vez puede usar los puntos finales XRM para cambiar los registros.

ACTUALIZACIÓN

O bien, puede intentar algo como esto sobre su inicialización servicio de CRM en el plugin (desenterrado de una de mis plugins) que sale de su flujo de trabajo sin tocar:

CrmService service = new CrmService(); 
//initialize service here, then... 

CorrelationToken newtoken = new CorrelationToken(); 
newtoken.CorrelationId = context.CorrelationId; 
newtoken.CorrelationUpdatedTime = context.CorrelationUpdatedTime; 

// WILD GUESS: Enforce unlimited depth ? 
corToken.Depth = 0; // THIS WAS: context.Depth; 

//updating correlation token 
service.CorrelationTokenValue = corToken; 

I Admito que realmente no recuerdo mucho sobre esto (el código data de hace aproximadamente 2 años), pero podría ayudar.

+0

Gracias de nuevo Alex. Sé que hay muchas maneras en las que podría diseñar una solución que logre el mismo objetivo, pero cada una tiene sus propias desventajas también. Quiero entender completamente los problemas que enfrento en este modelo antes de descartarlo sin más. El comportamiento que estoy viendo aquí no es consistente con mi comprensión de la documentación. Siento que es posible, pero puede que sea necesario hacer ciertas cosas de forma ligeramente diferente. –

+0

@Greg agregué un código que podría ayudar (o no, no tengo manera de probarlo) – Alex

+0

+1 Aunque es un enfoque más agresivo de lo que esperaba, esta es probablemente la ruta en la que habría ido en el fin. Sin embargo, afortunadamente comprenderá mejor por qué está ocurriendo esta pregunta. Intrigado por el anecdótico período de "60 minutos de inactividad" de Boone. –

Cuestiones relacionadas