I have set of custom activities, which are used in complex workflows.
I would like to make them (custom activities) persistable without having workflow in an idle state. It should be kind of failover system, so whenever something goes wrong during execution of a workflow it can be either:
- paused by a user (in anytime) and resumed later from the bookmark/point it was paused (for example user has noticed that an external system is down and he wants to pause the workflow for time being).
- in case of an unhandled exception we can restart execution from last bookmark/point in time
- stop of WorkflowApplication host can happen anytime and we can restart execution from last bookmark/point in time
I've worked for few days with workflow persistance, but I am not sure if I can achieve my goal with it. Why?
- I could use blocking bookmarks in each custom activity, but blocking a workflow and restarting it just for purpose of having it persisted doesn't look promising.
- I could use notblocking bookmarks, but I was not able to see them in database and resume from it.
Can you please advice me, it workflow bookmarks are the way to go here?
I see some light in notblocking bookmarks, but I cannot persist them and resume later on. Can you please give me some hints how to persist a nonblocking bookmark for later resume?
Edit:
In wf3 there was an attribute PersistOnClose
which would be enough for my requirement.
in wf4 it was replaced with Persist
activity, which could also be useful, however I do not want to have extra activities in my already complex workflows.
Ideally, it would be great to be able to execute context.RequestPersist(callback)
from NativeActivityContext
, however this method is internal (and everything what is inside it is not visible outside of original assembly.
Here is what I came with:
PersistOnCloseAttribute
is not an option, because I'm using WF4 and this attribute is only .NET 3.x WF.The solution is to use
Persist
activity in each custom made activity (has to extendNativeActivity
which can schedule child activities):In order to make it work, it has to be added to metadata as ImplmentationChild:
The last thing is to schedule child activity from Execute method (doesn't matter where, persistence will happen only after calling activity is completed*).
In order keep the workflow persisted after unhandled exception, this piece of code have to be added to WorkflowApplication:
*return from the
Execute
method doesn't necessarily mean that the activity is "completed" - i.e. there are blocking bookmarks inside activity (see drawbacks below).There are few drawbacks of this solution: