1
votes

I have a simple Windows Workflow 4.5 workflow (screen snapshot at end of post) hosted as a WCF service in IIS. I've set up persistence using the SQL Server store provided by Microsoft.

The workflow accepts a document ID and a boolean indicating if it needs to pause and wait on human activity (review by a human). If the workflow needs to wait, it has a Receive() activity that correlates on the document ID and pauses (which creates a bookmark behind the scenes). Else it runs to completion and routes the document.

Everything works perfectly as long as we don't reboot the server or do anything like recycling the app pool for the service. As I understand persistence, the workflow should be persisted after the configurable "Time to idle" period, such as encountered WHEN WAITING TO RECEIVE A MESSAGE... I've set this value to a a very aggressive one second.

However, in cases you'd expect in the real world for a long-running workflow, if we simulate a server crash by rebooting or recycling the app pool, the workflows waiting with Receive() never respond. Are we supposed to be doing something special to "rehydrate" the workflow after the server comes back up? Does correlation not work for workflows that are persisted?

The Receive() that never fires after the server reboot is highlighted in yellow in the workflow below:

enter image description here

1

1 Answers

1
votes

I think I found the answer to this one.

When you create a WCF Worflow Application in Visual Studio 2013, it starts you off with a template app that contains pre-wired Receive() and Send() activities. It's this receive, with CanCreateInstance set to true, that allows the workflow to be instantiated when a WCF message is received.

The problem seems to be that the Receive and Send, being tied together, are considered an operation that must be completed before the workflow can go idle. That is, even though I have the second Receive() call in the workflow and that receive does indeed create a bookmark and cause the workflow to wait for input, it can't actually enter an idle state. Not being to idle means the workflow can't be persisted.

You can see the Send() dangling at the end of the workflow snapshot I uploaded. I took this Send out the workflow now waits, persists, correlates, and resumes perfectly.

In retrospect, I believe I erred in thinking the pre-wired Send was there to provide some information about the WORKFLOW, when in reality it makes sense to think of it as a reply to the message that KICKED OFF the workflow--and nothing more. By inserting workflow logic between the initial Receive() and paired Send() provided as a template by Visual Studio, I inadvertently prevent the workflow from idling because the receive/send seem to be considered an atomic operation--at least as far as idling/persisting are concerned.