Persisting of Workflow in the file

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

 

This post contains one very simple working example of the WorkflowPersistenceService which persist workflow instances in the file store.

using System;

using System.Collections.Generic;

using System.Text;

using System.Workflow.Runtime.Hosting;

using System.Workflow.ComponentModel;

using System.IO;

using System.Workflow.Runtime;

using System.Diagnostics;

 

 

namespace Daenet.Workflow

{

    /// <summary>

    /// Implements the custom WorkflowPersistenceService, which persists workflow instances in the file.

    /// </summary>

    public class WFFilePersistenceProvider : WorkflowPersistenceService

    {

        /// <summary>

        ///

        /// </summary>

        /// <param name="folder">The folder where the instance will be persisted.</param>

        public WFFilePersistenceProvider(string folder)

        {

            m_Folder = folder;

 

            if (Directory.Exists(folder) == false)

                Directory.CreateDirectory(folder);

        }

 

        private string m_Folder = "WFPersistance";

 

        #region Serialization

 

        /// <summary>

        /// Performs the serialization of one activity. Invoked during dehydration.

        /// </summary>

        /// <param name="RootActivity"></param>

        /// <param name="id"></param>

        private void SerializeActivity(Activity RootActivity, Guid id)

        { 

            string filename = getFileName(ref id);

            lock (typeof(WFFilePersistenceProvider))

            {

                using (FileStream stream = new FileStream(filename, FileMode.OpenOrCreate))

                {

                    RootActivity.Save(stream);

                }

            }

        }

 

 

        /// <summary>

        /// Performs deserialization of persisted activity. Invoked during rehydration.

        /// </summary>

        /// <param name="RootActivity"></param>

        /// <param name="id"></param>

        /// <returns></returns>

        private object DeserializeActivity(Activity RootActivity, Guid id)

        {

            string filename = getFileName(ref id);

 

            lock (typeof(WFFilePersistenceProvider))

            {

                using (FileStream stream = new FileStream(filename, FileMode.Open))

                {

                    object Result = Activity.Load(stream, RootActivity);

                    return Result;

                }

            }

        }

        #endregion

 

        #region Private Members

 

        private string getFileName(ref Guid id)

        {

            string filename = m_Folder + "\\" + id.ToString() + ".wf";

            return filename;

        }

 

        private Guid getIdFromFileName(string fileName)

        {

            int pos = fileName.LastIndexOf("\\");

            if (pos == -1)

                throw new ApplicationException("Serialization in the root is not
                supported. Please specify the folder which will contain persisted files."
);

 

            string guidStr = fileName.Substring(pos + 1, fileName.Length - 4 - pos);

 

            return new Guid(guidStr);

        }

 

        #endregion

 

        #region Provider Members

        #region WorkflowProvider Interface Implementation

 

        protected override System.Workflow.ComponentModel.Activity

            LoadCompletedContextActivity(Guid scopeId,
            System.Workflow.ComponentModel.
Activity outerActivity)

        {

            Trace.WriteLine("Rehydration");

            object obj = DeserializeActivity(outerActivity, scopeId);

 

            return (Activity)obj;           

        }

 

        protected override System.Workflow.ComponentModel.Activity LoadWorkflowInstanceState(Guid instanceId)

        {

            Trace.WriteLine("Rehydration");

 

            object obj = DeserializeActivity(null, instanceId);

 

            return (Activity)obj;

        }

 

        protected override void SaveCompletedContextActivity(System.Workflow.ComponentModel.Activity activity)

        {

            Guid contextGuid = (Guid)activity.GetValue(Activity.ActivityContextGuidProperty);

 

            SerializeActivity(activity, contextGuid);

        }

 

        protected override void SaveWorkflowInstanceState
        (System.Workflow.ComponentModel.
Activity rootActivity, bool unlock)

        {

            // Remove this "if" statement, if you want to persist workflow in any status.

            if (rootActivity.ExecutionStatus == ActivityExecutionStatus.Executing)

            {

                Guid contextGuid = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty);

 

                SerializeActivity(rootActivity, contextGuid);

            }

        }

 

        protected override bool UnloadOnIdle(System.Workflow.ComponentModel.Activity activity)

        {

            return false;

        }

 

        protected override void UnlockWorkflowInstanceState(System.Workflow.ComponentModel.Activity rootActivity)

        {

 

        }

        #endregion

 

        public void PersistWorkflow(WorkflowInstance wInstance)

        {

            Activity rootActivity = wInstance.GetWorkflowDefinition();

            SaveWorkflowInstanceState(rootActivity, true);

        }

 

 

        /// <summary>

        /// This method traverses all serializaed wirkflow instances and loads Loads
       
/// persisted workflows.

        /// </summary>

        /// <returns></returns>

        public ICollection<WorkflowInstance> LoadPersistedWorkflows()

        {

            List<WorkflowInstance> persistedWorkflows = new List<WorkflowInstance>();

 

            string[] files = Directory.GetFiles(m_Folder, "*.wf");

            foreach (string file in files)

            {

                Guid id = getIdFromFileName(file);

                persistedWorkflows.Add(this.Runtime.GetWorkflow(id));

            }

 

            return persistedWorkflows;

        }

 

        /// <summary>

        /// Deletes all existing serialized files. After this call no workflow remains in the store.

        /// </summary>

        public void Clean()

        {

            string[] files = Directory.GetFiles(m_Folder, "*.wf");

            foreach (string file in files)

            {

                File.Delete(file);

            }

        }

        #endregion

    }

}

 

This code snippet shows how to programmatically add the custom workflow persistence service:

WFFilePersistenceProvider persistanceService = new WFFilePersistenceProvider("c:\\temp\\WFPersistance");

 

WorkflowRuntime runtime = new WorkflowRuntime();

 

runtime.AddService(persistanceService);

 

 


Posted Aug 29 2007, 10:35 AM by Damir Dobric
Filed under:

Comments

Zoki Manas wrote re: Persisting of Workflow in the file
on 04-02-2008 15:10

After using the class to serialize the workflows in separate files, how can i use it to read all persisted workflows not taking into the consideration the status of the workflow (terminated or waiting for event).

developers.de is a .Net Community Blog powered by daenet GmbH.