locked
State Machine workflow service unexpected message behavior RRS feed

  • Question

  • I have a *.xamlx workflow service running in IIS and have State1, State2 and State3.

    Trigger T1 (State 1 -> State 2) listens to "Start" message on Receive Activity.
    Trigger T2 (State 2 -> State 3) listens to "Proceed" message on Receive Activity.

    The problem I have is that i expect something like InvalidOperationException when my state machine is in State 1 and "Proceed" message is coming. However, it looks like it is just awaiting in queue and fails with timeout exception.

    How do I get an expected behavior here?


    Best regards, Alexander Efimov

    Monday, August 10, 2015 2:42 PM

Answers

  • Alexander,

    You are running into a situation where the workflow has both "protocol bookmarks" and "non-protocol bookmarks". "Protocol bookmarks" are created by the messaging activities (e.g Receive). "Non-protocol bookmarks" are bookmarks that are unrelated to messaging activities. And State activities create non-protocol bookmarks internally.

    This issue was reported when using "Pick" also - https://social.msdn.microsoft.com/Forums/vstudio/en-US/275f7817-1ec7-433c-89ba-fe48afd1dae8/wf4-wcf-send-message-at-wrong-time?forum=wfprerelease

    Here is an excerpt from my explanation on that thread:

    The root cause of the difference in behavior (timeout) when using a Pick or State activity to encapsulate the Receive for OperationB is that Pick and State activities create internal bookmarks that are unrelated to the bookmarks created by Receive activities.

    The bookmarks created by Receive activities (let’s call them “protocol bookmarks”) are treated in a special way in order to preserve the messaging protocol implemented by the workflow service.

    Imagine a scenario where the service has the messaging “protocol” of Operation1 followed by Operation2:

    Receive(Operation1)

    SendReply(Operation1)

    DoSomeOtherWork

    Receive(Operation2)

    SendReply(Operation2)

    If DoSomeOtherWork has asynchronous operations that may cause the workflow instance to go idle, they are going to create non-protocol bookmarks. These bookmarks will get resumed thru some other means, outside of the messaging protocol for the workflow service.

    So it is possible for Operation1 to complete and for the client to send Operation2 before DoSomeOtherWork is complete. We don’t want to reject Operation2 immediately. Instead, we hang onto the Operation2 message in hopes that the work being done by DoSomeOtherWork completes and the bookmark associated with that work gets resumed. Once DoSomeOtherWork completes, the protocol bookmark for Receive(Operation2) will get created and now the message from the client can successfully get processed.

    While DoSomeOtherWork is still outstanding, the message for Operation 2 is received. It discovers that there is no protocol bookmark for Operation2. We then check to see if there are any non-protocol bookmarks outstanding for the instance. If there are (as is the case when DoSomeOtherWork is still outstanding), we hang on to the message. But if there are no other non-protocol bookmarks, we immediately reject the message as being out of order.

    Starting in .NET 4.6, there is an AppSetting that you can specify in the web.config file of your service that controls how non-protocol bookmarks and out-of-order messages are dealt with. To configure the AppSetting, add this to your web.config file:

    <configuration>
      <appSettings>
        <add key="microsoft:WorkflowServices:FilterResumeTimeoutInSeconds"
    value="60"/>
      </appSettings>
    </configuration>

    The value of this "FilterResumeTimeoutInSeconds" specifies the length of time (in seconds) the workflow runtime hangs on to an out-of-order message before it times out. The default value is 60. A value of 0 specifies that it should not wait at all and reject out-of-order message with fault with the text:

    Operation '<operation-service-identifier>' on service instance with
    identifier '<workflow instance id guid>' cannot be performed at this
    time.
    Please ensure that the operations are performed in the correct order
    and that the binding in use provides ordered delivery guarantees.

    If the value is greater than 0, then you will still get a timeout exception after the specified time expires.

    Again, this new AppSetting is available starting in .NET 4.6. And this all assumes that BufferedReceive is NOT being used.

    This is also documented here: http://blogs.msdn.com/b/dotnet/archive/2015/07/20/announcing-net-framework-4-6.aspx?PageIndex=2

    Tuesday, August 18, 2015 10:51 PM

All replies

  • HI,

    You can use this way to raise InvalidOperationException.

    Starts the execution of the created workflow instance. WorkflowInstance.Start()causes the workflow runtime to raise the WorkflowStarted event, and the workflow instance is in a Running state. An InvalidOperationException is thrown if Start() is called on an already-started workflow instance.

    Further information: https://msdn.microsoft.com/en-us/library/Aa663362.aspx

    With regards,

    Angie


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, August 12, 2015 3:06 AM
  • Hi Angie,

    Thanks for the reply but it's not actually about starting workflows.

    Imagine workflow is already started. And I have a state machine in some intermediate State X.

    There is also State Y aside which would listen for Y in case machine is in that state.

    What I want to have is WF to throw some exception when workflow is in State X but got Y message instead of X.


    Best regards, Alexander Efimov

    Tuesday, August 18, 2015 12:53 PM
  • Alexander,

    You are running into a situation where the workflow has both "protocol bookmarks" and "non-protocol bookmarks". "Protocol bookmarks" are created by the messaging activities (e.g Receive). "Non-protocol bookmarks" are bookmarks that are unrelated to messaging activities. And State activities create non-protocol bookmarks internally.

    This issue was reported when using "Pick" also - https://social.msdn.microsoft.com/Forums/vstudio/en-US/275f7817-1ec7-433c-89ba-fe48afd1dae8/wf4-wcf-send-message-at-wrong-time?forum=wfprerelease

    Here is an excerpt from my explanation on that thread:

    The root cause of the difference in behavior (timeout) when using a Pick or State activity to encapsulate the Receive for OperationB is that Pick and State activities create internal bookmarks that are unrelated to the bookmarks created by Receive activities.

    The bookmarks created by Receive activities (let’s call them “protocol bookmarks”) are treated in a special way in order to preserve the messaging protocol implemented by the workflow service.

    Imagine a scenario where the service has the messaging “protocol” of Operation1 followed by Operation2:

    Receive(Operation1)

    SendReply(Operation1)

    DoSomeOtherWork

    Receive(Operation2)

    SendReply(Operation2)

    If DoSomeOtherWork has asynchronous operations that may cause the workflow instance to go idle, they are going to create non-protocol bookmarks. These bookmarks will get resumed thru some other means, outside of the messaging protocol for the workflow service.

    So it is possible for Operation1 to complete and for the client to send Operation2 before DoSomeOtherWork is complete. We don’t want to reject Operation2 immediately. Instead, we hang onto the Operation2 message in hopes that the work being done by DoSomeOtherWork completes and the bookmark associated with that work gets resumed. Once DoSomeOtherWork completes, the protocol bookmark for Receive(Operation2) will get created and now the message from the client can successfully get processed.

    While DoSomeOtherWork is still outstanding, the message for Operation 2 is received. It discovers that there is no protocol bookmark for Operation2. We then check to see if there are any non-protocol bookmarks outstanding for the instance. If there are (as is the case when DoSomeOtherWork is still outstanding), we hang on to the message. But if there are no other non-protocol bookmarks, we immediately reject the message as being out of order.

    Starting in .NET 4.6, there is an AppSetting that you can specify in the web.config file of your service that controls how non-protocol bookmarks and out-of-order messages are dealt with. To configure the AppSetting, add this to your web.config file:

    <configuration>
      <appSettings>
        <add key="microsoft:WorkflowServices:FilterResumeTimeoutInSeconds"
    value="60"/>
      </appSettings>
    </configuration>

    The value of this "FilterResumeTimeoutInSeconds" specifies the length of time (in seconds) the workflow runtime hangs on to an out-of-order message before it times out. The default value is 60. A value of 0 specifies that it should not wait at all and reject out-of-order message with fault with the text:

    Operation '<operation-service-identifier>' on service instance with
    identifier '<workflow instance id guid>' cannot be performed at this
    time.
    Please ensure that the operations are performed in the correct order
    and that the binding in use provides ordered delivery guarantees.

    If the value is greater than 0, then you will still get a timeout exception after the specified time expires.

    Again, this new AppSetting is available starting in .NET 4.6. And this all assumes that BufferedReceive is NOT being used.

    This is also documented here: http://blogs.msdn.com/b/dotnet/archive/2015/07/20/announcing-net-framework-4-6.aspx?PageIndex=2

    Tuesday, August 18, 2015 10:51 PM
  • Thank you, Jim. You answered my question.

    Best regards, Alexander Efimov

    Wednesday, August 19, 2015 4:52 PM