Persistere lo stato dei workflow su SQL Server

di Cristian Civera, in Windows Workflow Foundation,

Quando si realizzano flussi logici con Windows Workflow Foundation è probabile che questi durino nel tempo, per minuti, ore o addirittura giorni, e nella maggior parte dei casi perché deve interagire con l'utente attraverso i più disparati input.

Quando un'istanza di workflow viene creata, questa viene eseguita seguendo il flusso fino a quando alcune attività portano l'istanza in stato idle, viene liberato il thread di esecuzione, ma l'istanza resta in memoria, in attesa di input immessi nella coda tramite attività asincrone che terminano o eventi esterni che riattivano il flusso. Ovviamente l'istanza, restando in memoria, è vincolata alla vita del runtime e dell'host in cui l'ambiente gira e se questo cade (crash o chiusura del processo WinForm, ASP.NET, Console ecc) l'istanza e il suo stato vengono persi, vanificando quindi il lavoro; risultato che sicuramente nessuno vuole ottenere.

Per risolvere questo inconveniente, tra i servizi aggiungibili al runtime dei workflow, è presente la classe astratta WorkflowPersistenceService che rappresenta il servizio che ha il compito di persistere e di caricare le istanze dei flussi. Nel framework è presente un'implementazione di nome SqlWorkflowPersistenceService che persiste le informazioni su un database SQL Server appositamente preparato da Microsoft.

Per poter utilizzare questo servizio occorre quindi prima di tutto preparare il database lanciando gli script situati in C:\Windows\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN: SqlPersistenceService_Schema.sql (per la creazione delle tabelle) e SqlPersistenceService_Logic.sql (stored procedure utilizzate dal servizio). Una volta preparato il db è sufficiente creare il servizio configurandolo con la corretta connection string (l'utente deve essere almeno nel ruolo SQL state_persistence_users) in fase di preparazione del runtime:

WorkflowRuntime runtime = new WorkflowRuntime();

SqlWorkflowPersistenceService persistenceService = new SqlWorkflowPersistenceService("server=...;database=...;user=", true, TimeSpan.MaxValue, new TimeSpan(0, 2, 0));
runtime.AddService(persistenceService);

E' possibile fare lo stesso dalla configurazione contenuta nel file .config

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

    <PersistenceRuntimeExample>
        <CommonParameters>
            <addname="ConnectionString"value="server=...;database=...;user=" />
        </CommonParameters>
        <Services>
            <add
                type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,
                System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
                PublicKeyToken=31bf3856ad364e35"
                UnloadOnIdle="true"/>
        </Services>
    </PersistenceRuntimeExample>
</configuration>

Il parametro UnloadOnIdle (specificato anche come parametro nel costruttore della configurazione tramite codice) indica al motore di scaricare l'istanza del flusso dal runtime, fase che si distingue dalla persistenza che comunque viene effettuata.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi