Workflow Foundation > Articles > La persistance dans Workflow Foundation
       Accueil
       L'équipe


       Présentation
       Activités WF
       Articles
       Tutoriaux
       Trucs & Astuces


       Forum (MSDN)
       Téléchargements
       Ressources FR
       Annuaire des liens
       Formation (WW)


       Administration


 




Utilité et nécessité de la persistance dans Workflow Foundation

Lorsque vous vous lancez dans la modélisation d’un nouveau workflow avec Workflow Foundation, vous devez avoir en tête deux critères importants: quelle sera la durée de son cycle de vie et quel devra être son niveau de disponibilité.

Par cycle de vie on entend :

  • soit un cycle de vie court, c'est-à-dire une séquence d’actions s’exécutant sur un espace de temps relativement court : par exemple, un workflow qui va vérifier pour un document que plusieurs critères sont valides avant de l’envoyer par Email.
  • soit cycle de vie long, ou le workflow va avoir à se mettre en attente d’actions externes, celles-ci pouvant intervenir à tout moment, dans les secondes comme dans les jours à venir : par exemple, un workflow de demande de congés nécessitant une validation par plusieurs responsables hiérarchiques avant d’être approuvé.

Pour ce qui est de la disponibilité, un workflow modélisé avec Workflow Foundation va obligatoirement être hébergé par une application hôte de votre choix (Application console, winform, web, service Windows…), hors, ce choix est très important car c’est la disponibilité de votre application hôte qui va définir la disponibilité de votre workflow.

On ne peut par exemple pas imaginer, dans le cas d’un workflow long, de l’héberger dans une simple application console car celle-ci possède un cycle de vie trop limité et trop incertain : dans le meilleur de cas, le temps d’ouverture d’une session Windows. Par contre un service Windows tournant en tâche fond ou bien une application web hébergée par un serveur IIS de haute disponibilité peut s’avérer plus adéquate.

Maintenant, que cela soit l’application console ou le service Windows, aucun processus hôte n’est à l’abri d’incidents techniques. De plus on ne peut pas imaginer avoir plusieurs milliers d’instances de Workflow en attende d’écoute chargées en mémoire sans souffrir de problèmes de performances sur le serveur. C’est la qu’apparait la nécessité d’avoir un système de persistance des instances inactives dans un support différent que la mémoire système : une base de données, directement dans le système de fichier…

Le système de persistance répond donc à ces deux besoins :

  • soulager la mémoire utilisée dans le cas ou de nombreuses instances de workflow sont en attente
  • permettre de conserver les instances de workflow dans le cas ou l’application hôte nécessite de s’arrêter, que cela soit de manière naturelle comme l’arrêt d’une application Web après 20min d’activité ou bien de manière imprévisible comme en cas d’incidents.

Le service de persistance sert donc à soulager la mémoire en vidant dans un support choisit les instances de workflow lorsque cela est nécessaire ou demandé, mais aussi à recharger en mémoire celles-ci lorsqu’elles nécessitent de redevenir actives pour continuer leurs cycles de vie.

 

Cycle de vie

Le schéma suivant illustre le cycle de vie d’un workflow utilisant un service de persistance.

 

Configuration et activation

Avant toute chose, il est important de noter qu’un service de persistance n’est pas obligatoire pour un workflow, mais qu’il est impossible d’en avoir plus d’un seul actif. Dans le cas ou vous ne configurez pas de service de persistance, les instances de workflow seront conservées en mémoire jusqu'à ce qu’elles se terminent ou jusqu'à ce que l’application hôte soit interrompue (dans ce cas la, elles seront définitivement perdues).

Le service de persistance, comme quasiment tous les services de Windows Workflow Foundation, peut se configurer de deux façons :

Soit de manière déclarative, dans le code C# / VB de l’application hôte, par exemple pour le service de persistance SQL, fournit par défaut :

WorkflowRuntime workflowRuntime = new WorkflowRuntime();
string connection = "Initial Catalog=SqlPersistenceService;Data Source=localhost;Integrated Security=SSPI;";
workflowRuntime.AddService(new SqlWorkflowPersistenceService(connection));

Soit par une syntaxe déclarative dans un fichier de configuration de l’application hôte, pour le même exemple :

<configSections>
   <section name="WorkflowRuntime" type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</configSections>

<WorkflowRuntime Name="WorkflowRuntime">
  <CommonParameters>
    <add name="ConnectionString" value="Data Source=.\ Initial Catalog=SqlPersistenceService;Data Source=localhost;Integrated Security=SSPI;" />
  </CommonParameters>
  <Services>
    <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      UnloadOnIdle="true"
      LoadIntervalSeconds="5" />
  </Services>
</WorkflowRuntime>

Plusieurs paramètres sont configurables au niveau du service de persistance :

  • La chaine de connexion, obligatoire pour le service de persistance par défaut (SQLServer)
  • La propriété « LoadIntervalSeconds » qui, elle aussi pour le service par défaut, définit l’intervalle de temps entre chaque persistance
  • La propriété « UnLoadOnIdle » qui permet de forcer la persistance du workflow et donc la libération de la mémoire occupée par celle-ci, dans le cas ou l’instance entre dans un état d’attente

Pour utiliser le service de persistance pour SQLServer, il est nécessaire de préparer la base de données ciblée en y exécutant des scripts SQL. Deux sont nécessaires : « SqlPersistenceService_Schema.sql » qui créé les tables de persistances et « SqlPersistenceService_Logic.sql » qui créé les procédures stockées utilisées par le service. Dans la dernière version de Workflow Foundation, ces deux scripts sont présents dans le répertoire « C:\WINDOWS\WinFX\v3.0\Windows Workflow Foundation\SQL\EN », en compagnie de ceux utilisés pour le service de tracking.

Récupérer une instance de Workflow persistée

Lorsque l’on souhaite manipuler des instances de workflow, la première chose qui vient à l’esprit est d’utiliser la méthode « workflowRuntime workflowRuntime.GetLoadedWorkflows(); ». Le problème est que cette méthode ne s’appuie pas sur le service de persistance et n’est donc capable de récupérer que des instances de workflow présentes en mémoire.

Depuis la beta 2, Workflow Foundation propose une API s’appuyant sur le service de persistance. Par exemple les quelques lignes suivantes permettront de récupérer la liste de toutes les instances de workflow, persistées ou non :

SqlWorkflowPersistenceService persistance = (SqlWorkflowPersistenceService)workflowRuntime.GetService(typeof(SqlWorkflowPersistenceService));
IEnumerable<SqlPersistenceWorkflowInstanceDescription> instances = persistance.GetAllWorkflows();

Les instances de workflow sont toutes nommées par un identifiant unique de type GUID, une fois le nom de l’instance requise récupéré, un appel à la méthode « workflowRuntime.GetWorkflow(Guid instanceID); » va permettre de manipuler celle-ci.

 

Création d’un service personnalisé

Workflow Foundation ne propose par défaut qu’un seul service de persistance pour SQLServer 2000, 2005 et Express.

Cependant, le modèle est complètement extensible et vous allez rapidement pouvoir implémenter votre propre service de persistance. Le SDK contient d’ailleurs un exemple avec sources de service de persistance dans des fichiers, qui peut vous servir de bonne base de départ.

Globalement, il vous suffit d’hériter de la classe de base « System.Workflow.Runtime.Hosting.WorkflowPersistenceService » et de réécrire les quelques méthodes définissant la logique de persistance, comme « SaveWorkflowInstanceState » et « LoadWorkflowInstanceState ».

Une fois la classe représentant votre workflow écrite, son activation et son utilisation devient strictement similaire au service SQLServer. Si vous le souhaitez, vous pouvez bien sur ajouter des paramètres de configurations à celle-ci.

 

Liens divers

Florent SANTIN