Explicitly setting the CorrelationId on a CorrelatedBy<>

1,618 views
Skip to first unread message

Kevin Sigmund

unread,
Jul 5, 2015, 3:26:33 PM7/5/15
to masstrans...@googlegroups.com
The saga I've written is initiated by and initiates actions based on external events, none of which are in response to anything the saga has initiated, so naturally none of them have a Guid set.  I'm currently correlated those "external" messages based on a string and this is working fine so far in terms of associating them with the proper saga instance.

However, when I send a request "internally" (that is I'm publishing a request and expecting a response to another MT instance in my application), the response fails to correlate with the saga that sent the request (i.e. the CorrelationId is all zeroes).

I think this is because that the initial message that kicked off the chain of events had no CorrelationId (since as I mentioned it was initially correlated explicitly in the Event(() => ...) during the setup of the saga.

If I've diagnosed the issue correctly, it seems like there are two solutions:
1) Somehow set the Guid value of the CorrelaltionId on the Request I'm setting (but this seems difficult as it's a Guid and my instance's CorrelationId is a nullable Guid

2) Correlate by String the Request/Response chain initiated by the string-correlated "external" event.

Any thoughts on this?  I was hoping to, besides the explicit String-correlation of external events, having everything Guid-correlated, but maybe that's just not practical in this scenario.  Here's some code:

// Figure out that this external event is associated with this saga, based on a string
            Event(() => PackageCarrierScanned,
                x => x.CorrelateBy(instance => instance.NotificationSubscription.TrackingNumber, context => context.Message.TrackingNumber));

During(Subscribed, 
                When(PackageCarrierScanned)
                .Then(e =>
                {
                    MaybeDoSomethingHereToFixTheCorrelationIdProblem();
                })    
                .Request(SendNotifications, context =>
                {

                    return new SendNotificationsRequest(context, NotificationSubscription); // the context here as an all-zero CorrelationId
                }),

                When(Notified) // the response to the request which never gets called because the CorrelationId that MT is looking for is, again, all-zeroes
                .Then(e =>
                {
                    DoAnotherThing();
                    Console.WriteLine(e.Data.Message);
                })

Chris Patterson

unread,
Jul 5, 2015, 8:33:11 PM7/5/15
to masstrans...@googlegroups.com
Did you try something like this?

                Event(() => Started, x => x

                    .CorrelateBy(instance => instance.ServiceName, context => context.Message.ServiceName)

                    .SelectId(context => context.Message.ServiceId));

I haven't written the unit test yet, but this should give the saga instance a good correlationId for the request to use and correlate back to the saga instance.




--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/masstransit-discuss/38415a6b-60d8-4979-b673-857ee8b3f0ae%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris Patterson

unread,
Jul 5, 2015, 9:17:38 PM7/5/15
to masstrans...@googlegroups.com
So I modified my test to use an uncorrelated start message and it works.

The SelectId(context => NewId.NextGuid()) is what I used.

Kevin Sigmund

unread,
Jul 6, 2015, 12:13:53 AM7/6/15
to masstrans...@googlegroups.com
Hm, I may not be using this correctly, but I think that SelectId() isn't intended for what I'm wanting to do.

This particular event isn't the initial event that instantiates a saga, so at the point when the event in question is received the saga already has a CorrelationId, which is good.  What I'm looking to do is to ensure that the incoming message's CorrelationId gets set to that of the saga.

It seems like SelectId is meant to do the opposite (i.e. set the saga's CorrelationId to that of the message).
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

Kevin Sigmund

unread,
Jul 6, 2015, 12:20:24 AM7/6/15
to masstrans...@googlegroups.com
What seems to be be working, though it feels somewhat kludgy is defining the following in my request class:

        public Guid CorrelationId
        {
            get { return _context.CorrelationId.GetValueOrDefault(); }
        }

Because I know that this request will only be sent when the saga is past the "Initially" state and will have a CorrelationId defined, it appears to work.  However, barring something that lets me set the incoming message's ID (that results in the request being sent) to that of the saga's current CorrelationId value, I think it's either the above, or specify that the request is CorrelatedBy<string> and making that my "TrackingNumber" value from my earlier code sample.

Do either of those seem more "correct" to you?

Chris Patterson

unread,
Jul 6, 2015, 10:42:46 AM7/6/15
to masstrans...@googlegroups.com
So the Request doesn't use CorrelationId at all, it uses the RequestId property in the State class to track the pending request, and to correlate the response back. So the state machine having a correlationId or not doesn't matter.

When the Request is setup:


The property for tracking the requestId:


So as you can see the CorrelationId doesn't get used for requests from state machines...


To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Kevin S. Sigmund

unread,
Jul 6, 2015, 10:58:02 AM7/6/15
to masstrans...@googlegroups.com
Huh, that's weird then that what I did solved my problem.  I was kind of going by the fact that the request response wasn't being received by my saga and the fact that I saw two NHibernate queries, one for the saga with the 000-000-00...etc CorrelationId, and then one after that that was using the requestid.

Let me know if that makes sense, but either way I'll play around with it a little more.  

--
You received this message because you are subscribed to a topic in the Google Groups "masstransit-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/masstransit-discuss/B3YaIMjFWb8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Chris Patterson

unread,
Jul 6, 2015, 11:46:36 AM7/6/15
to masstrans...@googlegroups.com
Can you post a snippet (private or otherwise) of your state instance and state machine classes? I'm trying to understand why this is different.


Reply all
Reply to author
Forward
0 new messages