Search code examples
asp.net-coreredismasstransitautomatonymous

MassTransit saga with Redis persistence gives Method Accpet does not have an implementation exception


I'm trying to add Redis persistence to my saga which is managing calls to a routing slip (as well as additional messages to other consumers depending on the result of the routing slip) in the hopes that it will solve another timeout issue I keep getting.

However, I get an error message which goes in to my saga_error queue in RabbitMQ.

The error shown in the message is:

Method 'Accept' in type 'GreenPipes.DynamicInternal.Automatonymous.State' from assembly 'AutomatonymousGreenPipes.DynamicInternalc83411641fad46798326d78fe60522c9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation

My correlation configuration code is:

InstanceState(s => s.CurrentState);

Event(() => RequestLinkEvent, x => x.CorrelateById(context => context.Message.LinkId).SelectId(y => y.Message.LinkId));
Event(() => LinkCreatedEvent, x => x.CorrelateById(context => context.Message.LinkId));
Event(() => CreateLinkGroupFailedEvent, x => x.CorrelateById(context => context.Message.LinkId));
Event(() => CreateLinkFailedEvent, x => x.CorrelateById(context => context.Message.LinkId));
Event(() => RequestLinkFailedEvent, x => x.CorrelateById(context => context.Message.LinkId));

Request(() => LinkRequest, x => x.UrlRequestId, cfg =>
            {
                cfg.ServiceAddress = new Uri($"{hostAddress}/{nameof(SelectUrlByPublicId)}");
                cfg.SchedulingServiceAddress = new Uri($"{hostAddress}/{nameof(SelectUrlByPublicId)}");
                cfg.Timeout = TimeSpan.FromSeconds(30);
            });

The LinkId in the above code is always a unique Guid.

The issue seems to happen when the saga is reading back an event that has been sent from my routing slip (be it a success or failure event).

An example event interface that is not working is:

public interface ILinkCreated
{
    Guid? CorrelationId { get; set; }
    int DatabaseId { get; set; }
    Guid LinkId { get; set; }
    string LinkName { get; set; }
}

If I switch back to an InMemorySagaRepository everything works (locally). I've tried so many different combinations of things and have now hit a brick wall.

I've updated all packages to the latest version. I've also been checking my redis database and can see that the state machine instance goes in each time correctly.

I also saw that someone on Google groups had the same issue but there's no response to their post.


Solution

  • So to answer my own question and perhaps shine a light on my own stupidity. The issue was in fact being caused by how I had setup my StateMachineInstance.

    Instead of having CurrentState of type State as below:

    public State CurrentState {get; set;}
    

    I should have specified it as a string as such:

    public string CurrentState { get; set;}
    

    Now it can be deserialized in to the object correctly. I suspect this may have been causing my timeout issues with the InMemorySagaRepository on my staging server too.