Handling transition to state for multiple events

前端 未结 2 1469
梦毁少年i
梦毁少年i 2021-01-05 18:51

I have a MassTransitStateMachine that orchestrates a process which involves creating multiple events.

Once all of the events are done, I want the state to transition

2条回答
  •  旧巷少年郎
    2021-01-05 19:15

    The solution proposed by Chris won't work in my situation because I have multiple events of the same type arriving. I need to transition only when all of those events have arrived. The CompositeEvent construct doesn't work for this use case.

    My solution to this was to raise a new AllDataImported event during the MarkImportCompletedForLocation method. This method now handles determining whether all sub-imports are complete in a thread safe way.

    So my state machine definition is:

                During(ImportingData,
                When(DataImported)
                    // When we get a data imported event, mark the URI in the locations list as done. 
                    .Then(MarkImportCompletedForLocation),
    
                When(AllDataImported)
                    // Once all are done, we can transition to cleaning up...
                    .TransitionTo(CleaningUp)
                    .Then(CleanUpSources)
            );
    

    The IsAllDataImported method is no longer needed as a filter.

    The saga state has a Locations property:

    public Dictionary Locations { get; set; }
    

    And the MarkImportCompletedForLocation method is defined as follows:

        private void MarkImportCompletedForLocation(BehaviorContext ctx)
        {
            lock (ctx.Instance.Locations)
            {
                ctx.Instance.Locations[ctx.Data.ImportSource] = true;
                if (ctx.Instance.Locations.Values.All(x => x))
                {
                    var allDataImported = new AllDataImportedEvent {CorrelationId = ctx.Instance.CorrelationId};
                    this.CreateEventLift(AllDataImported).Raise(ctx.Instance, allDataImported);
                }
            }
        }
    

    (I've just written this so that I understand how the general flow will work; I recognise that the MarkImportCompletedForLocation method needs to be more defensive by verifying that keys exist in the dictionary.)

提交回复
热议问题