views:

149

answers:

1

Let's have a workflow consisted of Receive activity followed by Delay activity. The Receive activity has CanCreateInstance = true and the query (message) correlation is also provided. The workflow is hosted in workflow service and is persisted into the database immediately on idle.

WorkflowService service = new WorkflowService
{
  Name = "MyWorkflow",
  Body = new MyWorkflow(),
  Endpoints =
  {
    new Endpoint
    {
      ServiceContractName = "IMyWorkflow",
      AddressUri = new Uri("http://localhost:1234/MyWorkflow"),
      Binding = new BasicHttpBinding()
    }
  }
};

WorkflowServiceHost host = new WorkflowServiceHost(service);
string conn = "Data Source=...;Initial Catalog=...";
host.DurableInstancingOptions.InstanceStore = new SqlWorkflowInstanceStore(conn);
host.Open();

Now I send the message to the workflow and the runtime creates the first workflow instance. The correlation key is included in the message, of course. The workflow continues with Delay activity and is saved to the database and unloaded.

Let's assume the delay is long enough and I'll send next message with exactly the same correlation key. What happens? Both workflows are never woke up from the delay and never finished.

What do I wrong? Why workflow runtime doesn't protect me against this? Is there any way how to rescue both workflow instances?

Thanks for help!

+2  A: 

If you are using message correlation the key value in the message must match with a single active workflow. If you try to start a second workflow using the same key you will get an exception when trying to start the new instance. Now if you are using just a Receive without a SendReply you are creating a one way messaging scheme and there is no way to send the SOAP fault back to the client. So the client might not be aware of the error. You can still see this if you turn on tracing in your service and inspect the log files. However the easier option is to include a SendReply, even if you don't have normal response, as this results in a response message that can contain the fault message.

Maurice
OK, understand, thanks! What is still unclear how can I rescue those workflows. I can see both workflows persisted in database. Is there any way how to access those workflows from the code and do something, e.g. delete them to be able to use the correlation key again properly?
Petr Felzmann
Or maybe the solution for me is to not set workflow persistence immediately, but when the delay activity is started. Then the workflow send me the exception, but will not persisted itself. Could you confirm if I'm right, please?
Petr Felzmann
Message correlation is not related to persistence. The first is about routing messages to a specific workflow instance, the second about saving the state and being able to remove the workflow from memory. Message correlation is going to work exactly the same with workflow instances just in memory.
Maurice
Yes, I understand. But as I wrote in the question, I observe such bad behavior: after I send the second message then the first workflow get broken and the delay is never finished :-( This is the reason I asked details the in the followed comments.
Petr Felzmann
because if the workflow has no persistence then the delay is finished even I send the second message with the same correlation key. So from this observation I think there could be some influence of persistence.
Petr Felzmann
I think I must be missing part of the problem then. Workflow instances are not related so a failed attempt at starting a second workflow should not break the first workflow or have any other influence on it. So I guess it sounds like the second message is being processed by the first workflow instance and causing some kind of error there. If you add the EtwTrackingProvider to your workflow service host you should be able to see exactely what the error is and solve the problem.
Maurice