locked
Non content based correlation and receive activities RRS feed

  • Question

  • Hi,

    I'm currently testing the messaging activities and came down to a very simple scenario:

    I'm self hosting a sequential workflow with WorkflowServiceHost which includes two Receive activities, one after another. The service host is initialized with default endpoints for an HTTP URI on localhost and additionally a ServiceMetadataBehavior behavior with HttpGetEnabled set to true.

    * The first activity is set so the host will create new workflow instances (CanCreateInstance=true)
    * Each receive activity has a unique Operation- and ServiceContractname and there is no common content in the data passed to either of the two activities.
    * I created a service reference and used the generated client code to build a simple client application which will first send data to the first receive activity followed by data for the second receive activity.

    By enabling WCF message logging I noticed that both HTTP posts for the workflow service are obivously received but the second receive activity will not go on and just block. I'm assuming that this may be due to wrong correlation settings on my side yet I can't find a way how to tackle this problem correctly (e.g. using Correlation handles and the given properties on the Receive activities). Should I use a context binding, e.g. BasicHttpContextbinding, for this situation? If yes, how will this be handled compared to WF3.5 which was depending on instance GUIDs in that matter?

    Thanks and best regards,
    Mario
    Thursday, July 9, 2009 3:30 PM

Answers

  • Hi Mario,
    Yes, moving forward correlation is the mechanism that controls which service instance and which receive within the instance is used. Have you seen the Beta1 Hands On labs...particularly the "Introduction to Workflow Services" at http://code.msdn.microsoft.com/wcfwf4. You may find it useful.

    Thanks,
    Amy
    Monday, July 13, 2009 9:16 PM

All replies

  • To do a quick recap:

    in short: using a context-ful binding such as BasicHttpContextBinding and caching the context on the client side will work for this scenario.

    Reusing the <string,string>-dictionary client context of the first call to the workflow with the second client will do the trick, quite similar to the way it was handled in WF 3.5 . Again the key for the context must be named "instanceId" and its value has to be a GUID string.


    One thing that has changed compared to WF 3.5 is setting the context at the workflow side. In Matt Winkle's advanced workflow services talks we can often see that e.g. a send activity's Context property will be set to enable correlation. In WF 4.0 this property is no longer available.

    My question now is: am I to assume that the old WF 3.5 strategy to set the context property of a send activity is now superseeded by appropriate handling of the CorrelatesWith and related properties?

    Thanks and best regards,
    Mario
    Monday, July 13, 2009 2:26 PM
  • Hi Mario,
    Yes, moving forward correlation is the mechanism that controls which service instance and which receive within the instance is used. Have you seen the Beta1 Hands On labs...particularly the "Introduction to Workflow Services" at http://code.msdn.microsoft.com/wcfwf4. You may find it useful.

    Thanks,
    Amy
    Monday, July 13, 2009 9:16 PM
  • Well..

    to stick with the topic I don't see any correlation between my question and the proposed answer :) In case you folks are doing this due to quotas I will open up a new thread since my findings and questions have changed anyways.

    Thanks and best regards,
    Mario
    Wednesday, July 15, 2009 9:23 AM
  • Hi Mario,
    It seemed like you were asking basic questions about correlation so I thought looking at the lab sample might prove helpful. I'm sorry if it was too simplistic and it didn't give you the answer you needed. To answer the question "am I to assume that the old WF 3.5 strategy to set the context property of a send activity is now superseeded by appropriate handling of the CorrelatesWith and related properties?" the simple answer is yes. Within Content-based correlation there are two subtypes - one that uses user data for the correlation and one that uses a context. The first one, aka, the user data tends to be known as Content-Based correlation and the second as Context-Based correlation. The first method is more difficult to configure as it uses XPath to query the incoming message for the user data which is used to generate an ID for the message. The Context Correlation uses information in the message header rather than user provided data so the Context Correlation becomes simplier to configure. To setup this type of correlation you first need to implement one of the Context bindings such as BasicHttpContextbinding. Also, the first send must always be a two way to facilitate the setup up of the ID both sides are going to correlate on. This context will then be included in the message header. Explicitly you're going to set each Send/Receive with aa AdditionalCorrelations to an appropriate CorrelationHandle. After the first Send from the client additional sends will use CorrelatesWith and the CorrelationHandle from the first Receive. Here's an example for a service:

     

    Variable<CorrelationHandle> rrHandle = 

    Variable<CorrelationHandle> contextHandle = …

     

    Receive startRequest= new Receive()

    {

        AdditionalCorrelations = 

        {

          { CorrelationHandle.ChannelHandleName,  rrHandle }

        }

    };

    SendReply startResponse = new SendReply()

    {

        Request = requestStart ,

        AdditionalCorrelations =

        {

            { CorrelationHandle. FollowingContextHandleName,  ContextHandle}

        }

    };

    Receive followupRequest = new Receive()

    {

      CorrelatesWith = contextHandle

    }



    I hope this helps to clarify correlation for you but certainly follow-up with additional questions and if I don't have an answer for you I will get one of the services PMs to assist you. Also, there is no need to open an additional thread unless you feel that your subject has gone too far off topic.

    Also, as an FYI, correlation changes significantly with Beta2 so it is easier to configure. A CorrelationScope activity is being added to setup correlation implicitly for you.

    Thanks,
    Amy

    Thursday, July 16, 2009 10:11 PM
  • hi Amy,

    thank you very much, this is really helpful information! It also made much clearer to me the meaning of the string constants exposed by the CorrelationHandle class.

    You see, my requirement is to implement/prototype a conversation pattern using two workflows, so each workflow would be both sender and receiver as could be common in interorganisational orchestration scenarios. I'm not able to use the approach of realizing this by using exactly one SendAndReceivReply/ReceiveAndSendReply activity per workflow as in the general case the receiving workflow's answer is not fixed to exactly one type. (e.g. the reply could be an authorization document or a refusal document with unrelated structure)

    As you described, a context binding and two way messaging are needed, Workflow W1 would consist of a SendAndReceiveReply activity, followerd by one or more  ReceiveAndSendReply activities (probably stacked in a picker activity). Workflow W2 Would start with a ReceiveAndSendReply activity and one or more SendAndReceiveReply activities where exactly one is used to send the reply data:

    W1                                                W2
    SAR ----- Request Document ----> RAS
           <---- ACK with context -------
                                                              
    RAS <-------- Reply Data ----------- SAR
           -------------- ACK -------------->

    Till now I hit the wall enabling this scenario.
    More precisely I was not able to send any context information from W2 to W1 resulting in the fault "There is no context attached to the incoming  message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the in
    coming binding supports the context protocol and has a valid context initialized".

    Q: How would I circumvent this problem? Is it necessary to use the ContextHandleName constant ( " This identifies the handle as a .NET Framework context exchange correlation on the client.")?

    Thanks again and best regards,
    Mario
    Tuesday, July 21, 2009 3:03 PM