Certains de vos packages peuvent avoir besoin d’enregistrer/persister des données et vous devez savoir qu’à chaque mise à jour d’un package par sa sentinelle, l’ensemble du package est supprimé avant d’être redéployé.

Il existe deux possibilités pour persister les données :

  • Utiliser un stockage “hors Constellation”
  • Utiliser les StateObjects

Stocker en dehors de Constellation

Comme vous le savez, un package n’est ni plus ni moins qu’une application.

Vous pouvez donc utiliser n’importe quel système de stockage :

  • File System
  • Base de donnée en tout genre
  • Web service
  • Etc …

Libre à vous de stoker vos données où bon vous sembles mais attention si vous souhaitez diffuser votre package, vous ajoutez des prérequis pour l’installation de votre package.

Note sur le File System

Vous pouvez bien sûr stocker des données dans des fichiers. Par défaut le “CurrentDirectory” du package est son répertoire de déploiement. Prenez garde toutefois car à chaque déploiement du package par la sentinelle ce répertoire est vidé.

Vous devez donc utiliser un répertoire “externe” qu’on définira par un setting.

SerializationHelper

Notez que la librairie Constellation met à disposition la classe “SerializationHelper” dans le namespace “Constellation.Utils” permettant de sérialiser et dé-sérialiser facilement des objets en JSON ou en XML.

Vous disposez des méthodes :

  • SerializeToFile et DeserializeFromFile pour sérialiser/dé-sérialiser vers/depuis un fichier
  • SerializeToString et DeserializeFromString pour sérialiser/dé-sérialiser vers/depuis un string

Par défaut c’est le format JSON qui est utilisé mais vous pouvez définir le DataContractSerialiser (format XML) dans les paramètres de la méthode.

Utiliser les StateObjects comme stockage

Le principe est d’utiliser les StateObjects comme stockage, très utile pour sauvegarder/restaurer l’état d’un package.

Chaque package peut publier des StateObjects que ce soit de simple valeur ou de véritable objet complexe. A chaque (re)démarrage de votre package, tous les StateObjects du package sont purgés de la Constellation mais cependant vous avez la possibilité de les récupérer dans votre code avant cette purge.

Pour cela vous devez ajouter dans le manifeste du package (PackageInfo.xml) l’attribut “RequestLastStateObjectsOnStart” à true.

RequestLastStateObjectsOnStart

Ensuite dans votre code, vous devez le plus tôt possible dans le “OnStart” vous abonnez à l’événement “LastStateObjectsReceived“.

Cet événement sera levé lorsque votre package recevra ses anciens StateObjects du serveur avant d’être purgés. L’argument passé dans l’événement contient une liste des StateObjects avant purge.

Vous pouvez “bêtement” re-pusher l’ensemble des StateObjects sans aucune modification :

Grace à ce mécanisme, vos packages peuvent conserver des StateObject sur “leur état”.

Par exemple, imaginez un package “Brain” qui pilote l’allumage automatique des éclairages d’un jardin.

Ce package déclare un StateObjectLink vers un StateObject qui indique la luminosité extérieure. Si la valeur franchie un certain seuil, le package décide d’allumer ou éteindre les éclairages en envoyant un message pour déclencher un MessageCallback du package pilotant les éclairages.

Imaginez maintenant que suite à l’allumage automatique des éclairages par votre package vous décidez de les éteindre manuellement. Puis, quelques instants plus tard, pour diverses raisons vous devez redémarrer (ou mettre à jour) votre package “Brain”. Vos éclairages risquent de se rallumer car votre “Brain” n’a pas mémorisé qu’il a déjà réalisé cette action !

Pour ce genre de problématique, il est intéressant de stocker ces variables dans une classe d’état et de publier cette classe dans un StateObject qu’on pourra nommer “State”. Lorsque notre package redémarre, on demandera à Constellation de nous renvoyer les derniers StateObjects.

Cela nous permettra de récupérer le dernier état de notre package avant son redémarrage.

Par exemple, vous pouvez définir une classe d’état de la façon suivante :

Sans oublier d’ajouter un handler pour la restauration de l’état précèdent :

De cette façon vous pouvez à tout moment accéder à votre variable via votre classe statique “State.Current” et dès que vous changez une valeur, invoquez la méthode Save(), pour re-pusher votre “State” comme StateObject de votre package :

Persistance de données dans un package
Editer la page sur GitHub
Étiqueté avec :

Sur le forum :

  1. Hello,

    Quelle est la différence entre State et CurrentState dans les différents codes ? Es-ce une erreur d’inattention à la rédaction ? Sans avoir tout le code, c’est difficile de détecter d’où peut venir cette classe CurrentState :slightly_smiling_face:

    Bon courage !

  2. Bonjour Rom,

    Oui en effet c’est une erreur de ma part, State et CurrentState font référence à la même classe :wink:

    Je viens de corriger l’exemple !

    Merci du feedback

Continuez la discussion sur le forum Constellation

Participants