Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Patrice

Des infos sur WinFX, .net 2, etc.

[WF] Level 400 : Implémentation de la persistence dans Workflow Foundation

Windows Workflow Foundation propose un mécanisme de persistence de workflows qui permet de sauvegarder l'état d'un workflow qui est en attente d'un évènement extérieur ou qui est terminé.

Cela est particulièrement pratique pour les workflows qui ont une longue durée de vie car cela permet de sauver l'état de l'instance lorsque l'éxécution est en attente, donc de libérer la mémoire en supprimant l'instance de la RAM en permettant donc d'autres instances actives d'être en exécution en même temps.

Microsoft propose donc avec Worflow Foundation une couche de persistence dédiée à SQL Server. Des scripts SQL de création du schéma de la base (création de tables) et de création de la logique (procédures stockées, fonctions) sont disponibles dans le dossier d'installation du framework .net 3 (C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN) afin de créer une base compatible avec le mécanisme de persistence pour SQL Server proposé par WF.

WF contient donc une classe SQLWorkflowPersistenceService qui contient la logique pour persister des instances de Workflows dans une base crée à l'aide de ces scripts T-SQL.

 
Quid de la création d'un mécanisme de persistence pour Oracle ?

Le premier réflexe pour les plus feiniants (donc les bons développeurs ;) est de convertir les scripts T-SQL en PL/SQL afin de pouvoir les exécuter sous Oracle et ainsi créer les tables et procédures stockées nécessaires. Et d'ensuite regarder comment Microsoft implémenter le service de persistence pour SQL Server pour faire de même mais pour Oracle.

OK pour la conversion des scripts, si vous connaissez un minimum le SQL cela ne devrait pas poser trop de problèmes. Correspondances de types et de grammaire suffisent pour réaliser cette conversion.

 La partie la plus interessante se trouve dans l'analyse de l'implémentation réalisée par Microsoft.

Le premier réflexe que j'ai lorsque je souhaite comprendre rééllement comment fonctionne un élément du framework .net est de lancer Reflector. Comme le dit si bien Ingo Rammer en conférence "Lorsque vous recherchez des informations sur le framework, n'appuyez jamais sur F1 dans Visual Studio, ne recherchez pas dans l'aide, utilisez uniquement Reflector. La documentation peut contenir des erreurs et ne contient pas toutes les informations que l'on peut souhaiter, Reflector, lui, ne ment jamais !".

Un petit tour donc par Reflector pour se retrouver dans le namespace System.Workflow.Runtime.Hosting en train d'analyser la classe SQLWorkflowPersistenceService.

Premier constat cette classe hérite de WorkflowPersistenceService, une classe abstraite que l'on doit donc utiliser afin de créer un service de persistence (créer une classe qui hérite de WorkflowPersistenceService et overrider les méthodes souhaitées).

Deuxième information, la classe SQLWorkflowPersistenceService implémente l'interface IPendingWork. Cette interface doit être implémentée pour tous les services (et même les activités) qui doivent être exécutés à la fin d'une transaction. Si l'on prend le cas d'un service de persistence, il est logique que l'opération de persistence s'exécute à la fin de la transaction (si tout c'est bien déroulé) tout en étant en à l'intérieur du scope de la transaction (afin que la transaction ne soit pas validée si une erreur intervient durant la persistence de l'instance de workflow). Si vous souhaitez donc avoir le même comportement pour vos services et activités vous devez implémenter cette interface IPendingWork.

Passons à présent à l'analyse de la logique de persistence elle-même implémentée dans la classe SQLWorkflowPersistenceService en débutant par exemple par la méthode LoadWorkflowInstanceState. Après un rapide coup d'oeil à cette méthode ainsi qu'aux autres, on se rend compte que l'accès à la base de données est déportée vers la classe PersistenceDBAccessor qui a donc la responsabilité technique de l'accès à la base de données de persistence. Un rapide coup d'oeil aux méthodes de cette classe et l'on se rend compte que Microsoft a utiliser les objets génériques d'accès aux données introduits avec le framework .net 2 tels que DBConnection, DBCommand, etc. Nous avons donc une classe technique indépendante du SGDB utilisé.

Chouette ! Je vais donc pouvoir créer ma classe OracleWorkflowPersistenceService qui hérite de WorkflowPersistenceService et utiliser cette classe PersistenceDBAccessor afin de réaliser l'accès aux données à ma place.

Malheureusement cette douce idée est impossible car la classe PersistenceDBAccessor est marqué internal et sealed.WorkflowInsidePersistence.jpg

Il est donc impossible d'accéder à cette classe depuis une classe externe à l'assembly contenant PersistenceDBAccessor.

Le premier réflexe lorsque l'on rencontre des classes marquées internal ou encore sealed (dont on ne peut pas hériter) est de beugler et de pester violemment contre Microsoft. Nous souhaiterions en effet souvent en tant que développeur, bénéficier d'un framework et en faire ce que l'on souhaite.

Pourquoi marquer une classe comme internal et sealed ?

Marquer une classe sealed indique que l'on ne souhaite pas donner l'opportunité aux developpeurs d'hériter de cette classe. Dans le cas de PersistenceDBAccessor, cela est logique puisque cette classe technique est générique. Nul besoin d'hériter de celle-ci pour implémenter la même logique mais pour une base Oracle ou db2, cette classe se suffit a elle-même et n'a pas besoin d'être redéfinie. Si vous souhaitez modifier sa logique c'est qu'elle ne correspond pas à vos besoin et vous devrez donc créer une autre classe indépendante.

La classe est également marquée internal pour une bonne raison : PersistenceDBAccessor est une classe spécialisée. Elle se base en effet sur un schéma de base de données connu (celui indiqué dans les scripts SQL livrés avec le framework). Les noms des procédures stockées, des paramètres sont donc définis en dur dans le code. Elle ne fonctionne donc que pour un seul schéma de base de données. Rendre cette classe publique obligerait donc les développeurs souhaitant l'utiliser à créer une base respectant à la lettre ce schéma de base de données. Ce genre d'impératif étant incompatible avec un framework, les développeurs de Redmond ont marqué cette classe comme étant internal afin d'éviter que les développeurs l'utilisent directement.

Pourquoi avoir faire une classe technique générique utilisant des DBConnections et des DBCommand si la seule implémentation dans Workflow Foundation est SQLWorkflowPersistenceService à destination de SQL Server ?

Afin que les microsoftees puissent rapidement proposer un OracleWorkflowPersistenceService et/ou DB2WorkflowPersistenceService (sans toucher à l'archi existante), livrés avec les scripts SQL respectant le même schéma mais dans les différentes variantes SQL supportées par différents SGBD.

Cela sera donc peut-être au programme pour la V2 de Workflow Foundation... Wait and see...


Vous souhaitez néammoins savoir comment implémenter une persistence dans Oracle ?

 
Envie d'en savoir plus sur Windows Workflow Foundation ? RDV aux TechDays début février où j'animerais deux sessions qui traiteront exclusivement du sujet :

Level 100 : co-animé avec Frank Guidduci de Microsoft France

Level 400 : co-animé avec Grégory Renard de Wygwam

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Posted: vendredi 2 février 2007 09:59 par patrice

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01