Best way to synchronize several parallel processing steps in saga

900 views
Skip to first unread message

Alex Wheat

unread,
Oct 9, 2017, 12:41:59 PM10/9/17
to masstransit-discuss
hi,

lets say we have a saga with some "Processing" state. The processing may contains 1, 2, 3 or more steps that may be run in parallel mode. 

            During(Creating,
               
When(RecordCreated)
                   
.ThenAsync(async context =>
                   
{
                       
if (context.Data.TimeStamp > context.Instance.Updated)
                            context
.Instance.Updated = context.Data.TimeStamp;


                        await context
.CreateConsumeContext().Publish<Processing1>(new

                       
{
                           
CorrelationId = context.Instance.CorrelationId,
                           
Timestamp = DateTimeOffset.UtcNow,
                           
Index = context.Data.Index
                       
});


                        await context
.CreateConsumeContext().Publish<Processing2>(new
                       
{
                           
CorrelationId = context.Instance.CorrelationId,
                           
Timestamp = DateTimeOffset.UtcNow,
                           
Index = context.Data.Index
                       
});


                        await context
.CreateConsumeContext().Publish<Processing3>(new
                       
{
                           
CorrelationId = context.Instance.CorrelationId,
                           
Timestamp = DateTimeOffset.UtcNow,
                           
Index = context.Data.Index
                       
});
                   
})
                   
.TransitionTo(Processing)

               
);




Every processing may be finished with either Success of Failed message. 

Now the question, what would be the best way to sync the saga and understand that all processing finished (either successfully or not)?

Now what I have is a set of properties in State 
        public bool Processing1Finished { get; set; }
       
public bool Processing2Finished { get; set; }
       
public bool Processing3Finished { get; set; }


that I fill appropriately when the processing is finished
                When(Processing1Finished)
                   
.Then(context => {
                       
if (context.Data.Timestamp > context.Instance.Updated)
                            context
.Instance.Updated = context.Data.Timestamp;


                        context
.Instance.Processing1Finished = true;
                   
}),
               
When(Processing1Failed)
                   
.Then(context => {
                       
if (context.Data.Timestamp > context.Instance.Updated)
                            context
.Instance.Updated = context.Data.Timestamp;


                        context
.Instance.Processing1Finished = true;
                   
}),


I suspect that it's not quite right and there should be better and more elegant solution...

Alexey Zimarev

unread,
Oct 9, 2017, 1:36:12 PM10/9/17
to masstransit-discuss

Chris Patterson

unread,
Oct 9, 2017, 1:46:06 PM10/9/17
to masstrans...@googlegroups.com
Alexey is right, think composite and have a separate event for each parallel step, once all three are done, bingo.

Also, in your first code snipped, using Then() to update the Updated property, and after that, end the Then() closure and use .Publish() instead of calling CreateConsumeContext() so many times. Makes the code easier to understand and read, not to mention, just looks nicer.


On Mon, Oct 9, 2017 at 1:36 PM, Alexey Zimarev <azim...@gmail.com> wrote:

--
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-discuss+unsub...@googlegroups.com.
To post to this group, send email to masstransit-discuss@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/masstransit-discuss/08381407-e7de-4b36-9845-758d489c338c%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Alex Wheat

unread,
Oct 9, 2017, 2:11:29 PM10/9/17
to masstransit-discuss
Yeah, I didn't think about composite event... actually I just absolutely forgot about it! :(

Thanks for pointing me to the right direction! :)

Re Publish() instead of CreateConsumeContext() - that'e exactly what was my prev question about: Is it possible to send message from Saga that declared as interface? 

I have all messages declared as interface, so I just didn't decide for myself yet which of the options fits me better :)


On Monday, October 9, 2017 at 1:46:06 PM UTC-4, Chris Patterson wrote:
Alexey is right, think composite and have a separate event for each parallel step, once all three are done, bingo.

Also, in your first code snipped, using Then() to update the Updated property, and after that, end the Then() closure and use .Publish() instead of calling CreateConsumeContext() so many times. Makes the code easier to understand and read, not to mention, just looks nicer.

On Mon, Oct 9, 2017 at 1:36 PM, Alexey Zimarev <azim...@gmail.com> wrote:

--
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-discuss+unsub...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.

Michael Kaiser

unread,
Jan 27, 2019, 12:23:18 AM1/27/19
to masstransit-discuss
Why does the composite event happen BEFORE the last event it joins?
Message has been deleted

Tomasz Bobek

unread,
May 20, 2019, 5:40:29 AM5/20/19
to masstransit-discuss
What is the differenece of using .Publish() instead of calling CreateConsumeContext() ? Only that the code is easier to understand and read?  

Chris Patterson

unread,
May 20, 2019, 8:18:09 AM5/20/19
to masstrans...@googlegroups.com
Yes, easier to see the flow with .Publish().

--
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.
Reply all
Reply to author
Forward
0 new messages