WF4 Workflow Versioning Spike
Today I’m starting on another spike project. So far there are only questions to investigate, no answers. I’m sharing my plans with you because I believe doing so might help some of you and I’m hopeful that you might share your insights with me as we seek to solve this problem together.
But aren't you solving versioning in the next release?
Why yes – if you saw my session at PDC10 – Windows Workflow Futures you know that we are working on solutions for the next release. However, you have projects that are happening right now and we want to provide answers for you today.
WF4 Workflow Versioning Spike
What is "Versioning"?
"Versioning is the creation and management of multiple releases of a product, all of which have the same general function but are improved, upgraded or customized." – SearchSoftwareQuality.TechTarget.com
When developing solutions with Windows Workflow Foundation developers have two elements which must be versioned together as the system evolves over time.
- The Workflow Definition
- The Workflow Instance State
The Workflow Runtime uses a Workflow Definition to create a Workflow Instance. The Workflow Instance creates and updates the Workflow Instance State at runtime. This state includes information about the activities that we executing and the state of variables in the workflow as well as other internal data.
When the Workflow Instance is persisted, the Workflow Instance State is stored in an Instance Store. At some later time, the Workflow Runtime will create a new Workflow Instance and load the Workflow Instance State from the Instance Store intothe Workflow Instance.
Windows Workflow Foundation in .NET 4 does not provide explicit support for versioning. Yet we know that any serious implementation must provide a solution for versioning. The purpose of this spike project is to investigate the various dimensions of the versioning problem and to propose solutions.
Scope
Activity Library Versioning
This deals with how workflows resolve dependencies to assemblies which contain types that they require. This has been previously investigated and the results published in the following blog posts. This area is out of scope for this spike.
- WF4 Spike: Activity Versioning, GAC and Loose XAML
- WF4 Activity Versioning Solution
- WF4 Versioning Spike: How To Unit Test Activity Versioning
- WF4 Versioning Spike: IIS Hosted Workflow Services
Service/Data Contract Versioning
Versioning Workflow Services is very similar to the general purpose problem of versioning Web Services with regard to Service / Data Contracts. There are well known techniques and resources dealing with this problem therefore this area is out of scope for this project.
Workflow Versioning
While any activity can be considered a workflow, for the purposes of this project a Workflow is defined as the activity which is invoked by the workflow runtime via WorkflowApplication, WorkflowInvoker or WorkflowServiceHost.
These are questions that need to be investigated
- What happens when I change a workflow which has persisted instances?
- Are there any "safe" non-breaking changes I can make? If so, what are they?
- How would I know if I made a change that was not safe?
- Is there a way I can know what the version of a persisted instance is?
What happens when I change a workflow which has persisted instances?
To test this scenario
- Create a workflow that will be persisted.
- Run the workflow to create several instances in the instance store
- Update and deploy a new workflow definition
- Resume a persisted instance and note what happens
Are there any "safe" non-breaking changes I can make?
Try Changing a Workflow Definition in various ways
- Alter the activity tree by adding or removing activities before and after the persistence point
- Add / Remove variables
- Add / Remove arguments
- Alter property arguments on an activity
- Alter expression text on an activity
- Alter a type used by the workflow
How would I know if I made a change that was not safe?
Make a list of the results when various kinds of changes are made that cause incorrect behavior
Is there a way I can know what the version of a persisted instance is?
Investigate options for adding version information to the persistence store
Versioning Scenarios
These scenarios represent the target solution scenarios for investigation in this spike. The output of the spike is to produce working scenarios which I can demo showing techniques which achieve the goals.
Scenario: Side by Side Versions
Given
- Workflow V1 has been in production and has persisted instances
- Workflow V2 has been developed and will now be deployed
When
- Workflow V2 is deployed
Then
- Messages sent to existing workflow instances for Workflow V1 are received by Workflow V1 and instances will complete under V1
- Messages which create new workflow instances will create new instances for Workflow V2
So That
- Workflows complete under the version they started with
Questions
- How do we route messages to the correct workflow with minimal pain?
- What requirement does this place on the client?
- How can we minimize the coupling between the client and the service with regard to versioning?
Scenario: Bug in the Workflow
Given
- Workflow V1 has been in production and has persisted instances
- Workflow V1 has a bug and instances will fail or produce incorrect results if they complete under V1
- Workflow V2 has been developed with bug fixes and will now be deployed
When
- Workflow V2 is deployed
Then
- Workflow instances started under V1 are deleted and resubmitted to Workflow V2
- Messages which create new workflow instances will create new instances for Workflow V2
So That
- All workflows complete under V2
Questions
- How do we detect instances that need to be deleted?
- How do we resubmit?
- How do we avoid duplicate work problems when we resubmit work which has already been done?
Feedback
Ultimately this project is for you. My goal is to help you create robust long lived solutions and getting versioning right is a key element of that. Perhaps you have thoughts about my project. Are there areas I should investigate that are missing? Are there solutions that you have found worked well for you? Just leave a comment and let me know.
Comments
Anonymous
March 30, 2011
Omg. Ron, I just have no words. Just want to say thank you for all work you have done. Looking forward for new posts.Anonymous
March 30, 2011
Warning. Bad Eanglish. My opinion on versioning. I think it may be just enough in some cases to introduce some kind of workflow key-bookmarks (or regions, or containers). When workflow reaches this bookmark, the workflow instance should be aware about where it has stoped. At the momment we have idle instance with the data about the place where particular workflow instance is actualy stoped. Then we can take decissions about can the workflow be safly updated (We can safely update the part which is not executed yet if we work with simple sequential workflow for example). Then we compare two versions of the xamls, and update parts which is between key-bookmarks is subversion like manner, and take care about updating conflicts (variable deleted/introduce etc) For this system to work workflow definitions should be saved with versioning data in the persistance database. (Is it already done?) This is quiet obvious things, I belive you already thinked about the problem in this way. But anyway, I just want to deliver feedback, because this is the least thing that I can do to thank you for providing much smoother way to dive inside the WF4 world.Anonymous
March 30, 2011
The comment has been removedAnonymous
March 30, 2011
@Adam - Wow - great feedback . You raise some excellent points I will have to consider. @Dmitry - thanks - keep the ideas coming!Anonymous
April 02, 2011
I love your blog posts, and check the RSS feed daily. Great work, I've been waiting for something exactly like this (second only to a date on the vNext stuff ;). I wonder if there's a "hacky" interim solution similar to what you plan for the full vNext where something vaguely similar to Xamlinjector is used to modify the in-store view of the persistence data based on the deltas between the old and new workflow. It wouldn't even have to be fully automated - basically I know the difference between these two workflow definitions, what changes do I need to make to the persistence data to reconcile them. For example, I know I added a WriteLine between these two activites, so I'm going to have a program troll through persistence and do an "Insert(something)" between activities X and Y. Sounds like something MS would probably be loathe to officially support, though, and I understand the reasons why.Anonymous
April 03, 2011
@jvrobert I've got some ideas that I'm looking into. One thing is certain this investigation has been very revealing so far and will certainly drive some new thinking into our next release as well.