State Persistence

May 1, 2010 at 5:08 PM

Can you describe the state persistence handling and setup in WF4? How to pass parameters to the state machine? Must they be serialized first as well?

The non-support features of "State Query" and "External Control", i.e. SetState as in WF3 are crucial. Will they be available before formal release?

May 3, 2010 at 6:21 PM
Edited May 3, 2010 at 6:22 PM

StateMachine persistence is just like other acitivities persistence. There is no special things.  StateMachine activity has no arguments. I am not sure what scenarios you are talking about. Could you give a sample?

For "State Query" and "Set State",  we'll seriously consider it as an option to expose them before formal release. But currently, we didn't get strong customer data for "Set State".  Could you give a scenario in which you'll use set data? We are pretty curious for the reason why it is needed. :)

May 8, 2010 at 4:40 AM

Thanks for reply. I assume the state persistence in WF4 would be similar to that of WF3, where SQL scripts would be provided to create persistence tables and necessary stored procedures; and persistence service should be registered to the WF runtime.

The "Set State" is important especially in migrating data from the legacy systems to be re-developed. State objects must be set to various intermediate states in the workflow to continue operations in the new system. It also happens occasionally the state object is corrupted with unknown reason and events can no longer be sent successfully. It can be recovered only by resetting the object to the correct state. Of course, in this case, a brand new state activity (object) is created with the specified state given to replace the obsolete one.

May 10, 2010 at 5:45 PM
Edited May 10, 2010 at 5:46 PM

The persistence is similar.  For migrating data from legacy systems to a re-developed system, it belongs to dynamic updating. If an old state is seperated into serveral new states,  you could use additional conditional transitions to move to different new states.  If using SetState(), you need know some values from workflowInstance to decide which new state should be moved to. Then, you need do SetState outside of workflowInstance according to the values. It's not easy to use.

May 11, 2010 at 2:02 PM

It is not trivial to create a new workflow instance and force it to the desired intermediate state with conditional transition. It is, however, easy to detemine the correct intermediate state of a workflow based on the legacy data and call the SetState() directly. The following sample of 5 lines would do it all, where the "entity" stores also some basic workflow information like "state" and "workflowID".

 // instantiate a new workflow
                        Guid WorkflowInstanceID = WorkflowHelper.Instance.RunWorkFlow<Workflow.Payment>();

                        StateMachineWorkflowInstance instance = new StateMachineWorkflowInstance(WorkflowHelper.Instance.RunTime, WorkflowInstanceID);

                        // align with workflow state marked for the entity
                        instance.SetState(entity.State);

                        WorkflowHelper.Instance.RunWorkflow(WorkflowInstanceID);    // run workflow to transit to the specified state

                        entity.WorkflowID = WorkflowInstanceID; // now use this new workflow instance

 

May 11, 2010 at 5:26 PM
Edited May 11, 2010 at 5:29 PM

From my view, you made some assumptions here
Assumption 1: You know which StateMachine Instance you want.
In V3.0, it's easier because we have only 1 StateMachine for each StateMachineWorkflowInstance. In V4.0, we could have multiple StateMachine instances for each WorkflowInstance. It's not easy to identify those StateMachine instances from outside of workflow.

Assumption 2: You know which State you want to move to.
I believe you need some runtime data to make decision where it should go. E,g, some values stored in dependency properties. In V3.0, it's easy for you to get those data because all of them are just dependency properties. In v4.0, because of runtime difference, you may need extra workflow extension to export runtime data. Definitely, you can also use tracking or other customized output. But they are not as easy as the reading of dependency properties in V3.0.

Back to your scenario, actually you need get runtime data for all StateMachineInstances, then call SetState() accordingly. Using conditional transition, you just need move this work into StateMachine from outside of workflow.  From my view, using SetState() in Workflow V4.0 wouldn't make things easier in your case.

 

May 16, 2010 at 5:02 AM
Xianfeng wrote:

From my view, you made some assumptions here
Assumption 1: You know which StateMachine Instance you want.
In V3.0, it's easier because we have only 1 StateMachine for each StateMachineWorkflowInstance. In V4.0, we could have multiple StateMachine instances for each WorkflowInstance. It's not easy to identify those StateMachine instances from outside of workflow.

Assumption 2: You know which State you want to move to.
I believe you need some runtime data to make decision where it should go. E,g, some values stored in dependency properties. In V3.0, it's easy for you to get those data because all of them are just dependency properties. In v4.0, because of runtime difference, you may need extra workflow extension to export runtime data. Definitely, you can also use tracking or other customized output. But they are not as easy as the reading of dependency properties in V3.0.

Back to your scenario, actually you need get runtime data for all StateMachineInstances, then call SetState() accordingly. Using conditional transition, you just need move this work into StateMachine from outside of workflow.  From my view, using SetState() in Workflow V4.0 wouldn't make things easier in your case.

 

 Thanks for reply

Assumption 1: I am not clear about the new concept of creating/loading an instance from the State Machine Workflow Activity in WF4. In WF 3.0 we create one from the corresponding service registered in the workflow runtime or ask the service  to load it according to the passed GUID. Is this completely changed in WF 4.0?  I wonder the State Machine workflow activity is like a class and the correspnding workflow instance is like an object of this class. Thus, this class to object mapping should be one to one ? What is new in WF 4 and why?

Assumption 2:  It is a bit mis-understanding here. We are talking about creating the state machine workflow instances from the legacy system.  For instance, we would like to implement a "Payment
" state machine workflow in the new system to represent data in the legacy system (i.e. a re-development of the legacy system). Such Payment workflows may not be in its initial state. From the legacy system data, we would easily know that the payment (data) has been cancelled, pending for bank clearance, settled, etc. This should normally be a flag/status column in the legacy database. In the new system, we would like to create the corresponding "Payment" state machine workflow instances and set their states to that are derived from the legacy database. In WF 3.0, this can easily be done by a SetState() system call.

 

May 17, 2010 at 2:59 AM

1. In V3.0, actually we only have 2 kinds of workflow instance. One is Sequence and the other is StateMachine. StateMachine only can be root activity of a workflow. It means a Sequence activity cannot contain StateMachine. In V4.0, the situation is changed. Any activity can be root activity and any activity can be non-root as well.  So a Parallel activity can have multiple StateMachine in different branches. When it gets running, you may have several running StateMachine activity instances within a single workflow instance whose root activity is the Parallel activity.  In this case, it's hard to identify the different StateMachine instances.

2.  Understood what you said. It's interesting to see how it help in migration of different StateMachine definitions. We'll seriously re-evaluate the importance of this feature.  Thanks a lot for your feedback.