0

Is it possible to match an incoming message with a saga that doesn't have a 1 to 1 correlation of Id or property? I'm looking at doing something like the following but CorrelateBy does not seem to hydrate the saga or trigger off any processing.

    public interface SubmitOrder
    {
        Guid OrderId { get; }

        string[] ItemIds { get; }
    }

    public interface ItemStockExhausted
    {
        string Id { get; }
    }

    public class OrderState :
        SagaStateMachineInstance
    {
        public Guid CorrelationId { get; set; }

        public string[] ItemIds { get; set; }

        public int CurrentState { get; set; }
    }

    public class OrderStateMachine :
        MassTransitStateMachine<OrderState>
    {
        public OrderStateMachine()
        {
            InstanceState(x => x.CurrentState);
            Event(() => SubmitOrder, x
                => x.CorrelateById(context => context.Message.OrderId)
            );

            Event(() => ItemStockExhausted, x
                => x.CorrelateBy((state, context) => state.ItemIds.Contains(context.Message.Id))
            );

            Initially(
                When(SubmitOrder)
                    .Then(x => x.Instance.ItemIds = x.Data.ItemIds)
                    .TransitionTo(Submitted));

            During(Submitted,
                When(ItemStockExhausted)
                    .Then(x => { /* Do something */ })
                    );
        }

        public Event<SubmitOrder> SubmitOrder { get; private set; }

        public Event<ItemStockExhausted> ItemStockExhausted { get; private set; }

        public State Submitted { get; private set; }
    }

Not sure if it makes any difference but I'm using the MongoDB persistence.

Kevin Smith
  • 13,746
  • 4
  • 52
  • 77
  • 1
    From reading the [documentation](https://mongodb-documentation.readthedocs.io/en/latest/ecosystem/tutorial/use-linq-queries-with-csharp-driver.html) it would appear that MongoDb supports `Contains` in the LINQ query, so it _might_ work as you've shown above. The suggestion below to log the query is a great one if you're seeing issues. – Chris Patterson Jan 11 '20 at 00:43
  • Thanks @ChrisPatterson the query in mongo was working perfectly fine it was actually my silly mistake of an exception happening once it was being processed. – Kevin Smith Jan 11 '20 at 19:32

1 Answers1

1

Correlation by the query is possible for Saga persistence providers that support queries. MongoDB persistence provider supports using queries but you need to remember that not LINQ queries translate to MongoDB queries properly.

In your case, I would advise enabling MongoDB query tracing, like it's suggested in this question: How do I log my queries in MongoDB C# Driver 2.0?

Some persistence providers, specifically those that are using key-value databases like Redis, won't support the correlation by queries but they normally throw the "unsupported" exception as soon as you try using a query.

Alexey Zimarev
  • 17,944
  • 2
  • 55
  • 83
  • I enabled profiling via `db.setProfilingLevel(2,1)` and it was querying back the correct saga, the actual problem was within a `Then` statement throwing an exception and it just getting swallowed ‍♂️ – Kevin Smith Jan 11 '20 at 19:30
  • Exceptions don't get swallowed, are you calling an _async_ method and not awaiting the result (using `.ThenAsync`)? – Chris Patterson Jan 12 '20 at 15:09