具有 Redis 持久性的 MassTransit saga 给出了 Method Accpet does not have an implementation exception

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

我正在尝试将 Redis 持久性添加到我的 saga 中,它管理对路由单的调用(以及根据路由单的结果向其他消费者发送的附加消息),希望它能解决另一个问题我不断收到超时问题。

但是,我在 RabbitMQ 中的 saga_error 队列中收到一条错误消息。

消息中显示的错误是:

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

我的相关配置代码是:

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);
            });

上面代码中的LinkId始终是唯一的Guid。

当 saga 回读从我的路由单发送的事件(无论是成功事件还是失败事件)时,问题似乎发生了。

一个不起作用的示例事件接口是:

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

如果我切换回 InMemorySagaRepository 一切正常(本地)。我尝试了很多不同的组合,现在却碰壁了。

我已经将所有软件包更新到最新版本。我也一直在检查我的 redis 数据库,可以看到状态机实例每次都正确进入。

我也看到 Google 群里有人遇到了同样的问题,但是 post 没有回复。

这里的问题是request-response。

它是这样工作的:

  1. MT将请求id放入saga状态属性UrlRequestId
  2. 请求已发送
  3. 您收到回复,回复中包含请求者地址和请求 ID header
  4. MT 使用 saga 存储库 找到 使用 repo.Find(x => x.UrlRequestId == message.Headers.RequestId) 的实例(因此这不是真正的代码,但实际情况是这样)
  5. Redis(或任何其他 KVS)不支持查询,因此我们也不支持 saga 存储库中的查询,您会得到 "not implemented" 异常

您的响应相关规范无效,因为 Request 总是使用 headers 来查找响应所属的 saga 实例。

您可以通过不使用 request-response 来解决此问题,而是使用 context.Publish(new LinkCreatedEvent { ... , CorrelationId = context.Message.CorrelationId }) 并使用通常的相关性发出事件。

所以要回答我自己的问题,也许可以照亮我自己的愚蠢。这个问题实际上是由我设置 StateMachineInstance 的方式引起的。

而不是像下面这样使用 State 类型的 CurrentState:

public State CurrentState {get; set;}

我应该将其指定为字符串:

public string CurrentState { get; set;}

现在可以正确反序列化到对象中了。我怀疑这也可能导致我的登台服务器上的 InMemorySagaRepository 出现超时问题。