3

我们有两个长时间运行的 saga,它们都运行了无限时间并响应超时。第一个每 15 分钟订阅一次超时,第二个每 24 小时订阅一次。每个 saga 都会跟踪自己的执行时间,并在开始运行和完成时通知其他 saga。由于数据库争用,这些 saga 负责的批量数据加载无法同时运行。

当第一个 saga ( Saga A- 15 min) 开始时,它首先检查(使用内部变量)以查看第二个 saga ( Saga B- 24 hr) 当前是否正在运行。如果不是,它开始它的处理步骤(脱壳到另一个进程,并随着时间的推移轮询它以查看它何时完成)。这两个 sagas 通过发送消息进行通信,以便在它们启动或完成时相互通知。

出于某种原因,这在两个层面上对我来说似乎很臭:

  1. 我们基本上有一个永远不会完成的单例传奇。这本身就是一种反模式吗?
  2. 我们双向发送消息的唯一目的是修改状态。似乎应该有更好的方法来处理这种情况。随着 NSB 4.0 的发布,我们开始在执行sending命令时遇到错误。当我们改用 pub-sub 方法时,错误就被清除了。

这是否被认为是 NServiceBus 实现反模式,对于这种需求是否有更好的模式?

4

1 回答 1

2

一般来说,我不认为 sagas 相互通信是一种反模式。但是,在您的具体情况下,它听起来确实很臭。

从你所说的行为来看,这似乎是一个单一的传奇。一个 saga 可以请求多个不同类型的超时。因此,您可以有效地合并这些 saga,但随后您将能够摆脱所有仅出于修改兄弟状态的目的而存在的消息,因为状态将被共享。

然而,在一般意义上,sagas 可以进行交流是非常好的。应谨慎对待通过命令执行此操作,因为这会在两者之间产生直接耦合,尽管这仍然是可能的。一个示例是父子 saga 对,其中父工作流命令子工作流开始,但子工作流是独立的,直到它回复其父工作流已完成。我们只是意识到这些是同一服务边界内紧密耦合的进程。我们这样做可能只是为了让每个 saga 更加专注,或者因为父级使用不同的数据启动多个子 saga。

一个更好的例子是通过事件进行 saga 通信。一个 saga 会发布一个事件,另一个 saga 会用自己的长时间运行的过程来响应。这一切都是解耦的,很好。但是,如果第二个 saga 发布第一个响应的事件,那么即使您正在使用事件,您也创建了一个循环,因此它与此时的命令并没有什么不同,尽管它仍然与任何其他外部订户。

于 2013-08-15T13:41:37.003 回答