问题标签 [saga]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1004 浏览

command - NEventStore:传奇,命令,而不是丢失它们

NEventStore:5.1
简单设置:WebApp (Asp.NET 4.5) == 命令端

我正在寻找不丢失命令的“正确”方法,着眼于 sagas/process-managers,它们可能会无休止地等待从实际上从未处理过的命令产生的事件。

旧:调度员

我最初使用同步命令,但着眼于sagas/process-managers,我认为首先存储它们然后通过 SyncDispatcher (或 AsyncDispatcher) 获取它们会更安全。否则,我担心的是,如果 saga 尝试发送命令并且由于app-crash/powerloss/...导致命令未完成,它将丢失并且没人会知道

所以我创建了一个命令流并将每个命令附加到它上面。如果该IsDispatched命令已被处理,则显示。
那行得通。

PollingClient 和 Command-Stream

现在调度程序已经过时,我切换到PollingClient. 我丢失的是Dispatched信息。

出现了一个启动问题:
我天真地从当前最新的检查点开始轮询,但是当应用程序重新启动时,有可能在崩溃之前存储了命令但没有执行,因此丢失了(这实际上发生了)。

我刚刚想到了这个想法
将命令的基本结果作为(非域)事件存储在另一个流中
此流将包含CommandSucceededCommandFailed事件。
每当应用程序启动最新的 command-id 或 command-checkpoint-number 时,就会提取用于在该命令之后立即加载命令...

问题

  • 我担心的是,同步命令处理会导致丢失传奇生成的命令的危险,错了吗?如果是,为什么?
  • 这通常是一个好主意:一个大的命令流吗?
  • 这通常是一个好主意:将通用命令结果事件存储在流中吗?
0 投票
1 回答
61 浏览

azure - NServiceBus AzureSagaPersistence 架构问题

我通过添加另一个 DateTime 属性更新了我的传奇数据类,一切都变得糟糕透顶。架构没有更新,我开始在每条 saga 消息上都出现异常,但那里没有重要数据,所以我删除了表。

从那时起,saga 数据表就是这样创建的: 在此处输入图像描述

架构中不存在来自 Saga 数据类的字段。

这是我的传奇数据类:

那里有什么问题?在我删除 saga 数据表之前,它非常好。

更新:我从我的数据类中删除了第二个 DateTime 字段,再次删除了表格并开始工作。为什么会这样?

0 投票
1 回答
581 浏览

nservicebus - NServiceBus saga Unique attribute

I have a saga data class with one property marked by Unique attribute. However, this didn't prevent NServiceBus from creating several sagas with identical values in this field.

Here is my data class:

Here is the mapping:

Here is how data gets its values:

And here is what I see in the saga persistence table (Azure table storage):

Does it suppose to work like this or may be I am missing something?

enter image description here

0 投票
1 回答
127 浏览

c# - Saga 等待状态值

我有一个 Saga 应该等待特定的 Database-Value 被更改。我如何实现这一目标?

例子:

当该订单的布尔“已批准”为真时,我想发送一封邮件。但这可能需要数小时甚至数天。我如何告诉 Saga 在几个小时后再次检查?我是 Sagas 和 NServiceBus 的新手,所以答案可能很简单,但我只是没有找到。

0 投票
0 回答
49 浏览

c# - 为什么我的 RequestTimeout 会被以下配置破坏?

我在 NServiceBus 中设置了一个 Saga 来包含事件的一些逻辑进展。任何事件都被很好地拾取,几乎所有的 Saga 功能都运行良好,这包括将 Saga 标记为完整,检索 Saga 数据等。

被打破的一件事是我的RequestTimeout(TimeSpan.FromMinutes(45))。经过多次调试,我发现以下行是罪魁祸首:

将其注释掉,而是在<UnicastBusConfig>my 部分添加一个端点App.config,它起作用了。有没有人经历过这种奇怪的事情,或者任何人都可以解释为什么配置该特定参数可能会使我的超时请求不起作用?

0 投票
1 回答
145 浏览

nservicebus - 是否应该使用 sagas 来保持处理程序执行的进度?

我有一个处理程序,其工作是获取对象列表,并为该对象列表中的每个项目发布一个事件。这可能类似于下面的代码:

我的用例是我希望 message.List.Count 很棒,因此 foreach 循环可能需要一些时间。

因此,假设我已经处理了 100 个条目对象中的 50 个,那么 Bus.Publish(entry) 由于某种原因而失败。处理程序将根据我的重试策略重试,但是,它现在将从头开始处理所有 100 个条目。

这并不理想,所以我想在某个地方坚持进步。由于我使用 MongoDB 作为持久层,我想我可以将我的 Handler 包装在 Saga 中。Saga 将跟踪所有已处理的条目,希望如果 Handler 失败,它将重试并检索 Saga 并记录它之前取得的进展。

然而,我的快速测试让我假设在 Handler 完成执行之前不会提交 Saga(在本例中为 MongoDB)。因此,对于我的用例,这没有帮助。

我的主要问题是我是否可以在 Handler 运行完成之前的某个时间点将 Saga 提交给数据库。这给了我 Saga 的其他一些好处,而我不必在每个条目都被发送到 Publishing 之后编写自己的持久性。

我的第二个问题是,如果这确实可能,我应该在这个特定的例子中这样做吗?这是对 Saga 的有效使用还是替代方法合适?

0 投票
1 回答
254 浏览

c# - 通过 Saga ID 关联聚合而不是附加聚合根

这是我的第一个问题,如果不清楚或不完整,请原谅,让我知道如何提供更多信息。

我正在尝试使用 CQRS + ES 构建电子邮件票务系统。因此,电子邮件被加入到对话中(有点像 Outlook 对话,但加入的标准不同),然后这些对话被分配一张票,人们可以与之互动(标记它,更新它的状态,添加注释......)。

目前,一旦收到邮件,就会创建一个引发MailReceived事件的新邮件聚合。
ProcessManager路由器(或传奇路由器)尝试根据条件找到匹配的“ConversationSaga”或创建一个新的。saga 发送一个命令,将对话 Id 分配给 Mail 聚合 --> 引发ConversationAssigned邮件。

最后一个事件ConversationAssigned被 Ticketing 有界上下文拦截,该上下文会根据对话 Id 生成票证或更新现有票证。创建/更新票证后,该事件将被路由到 ConversationSaga 以发送所需的命令(ApplyTicketToMail --> MoveMailToFolder --> ...)

我的问题是:
1-使用 Saga Id 作为将多个邮件链接在一起的对话 Id 是否异常?
2-我正在检查创建Conversation Aggregate根的可能性,但我对事件溯源仍然很陌生,并且不知道如何处理 AggregateRoots 中的事件溯源实体(我需要 Mail 作为事件溯源聚合)。

PS:我使用的是 C#,带有 MsSql DB 和 nhibernate,并且消息传递是通过 RabbitMq 进行的。

0 投票
1 回答
521 浏览

multi-tenant - 制作 Automatonymous sagas 多租户

在 Chris Patterson的帮助下,我们成功地将我们的多租户策略与 MassTransit 集成。然而,我们在获得我们的(自动)传奇多租户时遇到了困难。我有一些有用的东西,但我对它一点也不满意。我们正在使用“每个租户的模式”数据库策略,但如果这是解决问题的最干净的方法,我们愿意为 sagas 灵活使用它。

我们在所有消息的标题上都有租户 ID。我们将其从传入消息中刮下,IConsumeContext<>然后将其放回IPublishContext<>传出消息中。这很好用,ISagaRepository<>.GetSaga(...)因为它的参数之一是IConsumeContext<>. 问题是,当我们调用其他ISagaRepository<>方法时,它们没有IConsumeContext<>,并且我们无法在存储库中按租户进行过滤。如果我们坚持当前的数据库策略,我们就知道租户,所以我们知道要命中什么模式。如果我们更改为拥有集中的租户表,我们必须在过滤中包括租户,因为与之相关的事物在租户之间不一定是唯一的。

根据我目前的理解,这PropertySagaLocator<,>似乎是关键点。在它的Find(IConsumeContext<>)方法中,我们有需要访问的租户上下文,但它没有被传递到 saga 存储库。

因此,在我目前的尝试中,我为多租户创建了一个属性 saga 定位器,它与一个专门的租户 saga 存储库一起工作,并为它提供了.Where(...)适当使用其方法所需的租户上下文。但这就是它变得丑陋的地方。具体PropertySagaLocator<,>类正在由 Automatonymous 实例化,因此要交换它,我必须从 Automatonymous 的边缘开始,从.StateMachineSaga(...)扩展方法之一开始,并一直交换具体类,直到它与 MassTransit 集成通过使用PropertySagaLocator<,>因为它是一个具体类的链,一路向下实例化彼此。我对通过 Automatonymous 进行如此深入的切割感到不舒服,但在我看来,无论我们采用“每个租户的架构”策略还是切换它,我们都需要在同一点进行集成。

另一个方面是,当使用 Automatonymous 表示法时,我们需要将租户 ID 放在传出消息.Publish(...)中。我目前这样做的方式是使用装饰器模式ServiceBus,目前我注入装饰的、特定于租户的服务总线的时间点是总线从消费上下文复制到实例状态时,即在我的saga 消息接收器GetHandlers()方法的覆盖。

有没有人有如何将 Automatonymous sagas 与多租户集成的经验?我们现在所做的似乎是侵入性的,我们希望找到更自然的接缝。

0 投票
1 回答
310 浏览

design-patterns - CQRS - 业务验证规则

我正在使用 CQRS 和事件溯源模式创建一个系统(我希望如此)。我必须根据一个读取模型存储的统计数据和不同读取模型存储的用户设置数据(均由过去的事件创建)做出业务决策。什么是放置业务逻辑规则的好地方,其结果取决于该数据?

  • 它是一个命令(我可以在命令中获取存储在读取模型中的数据吗)?

  • 其他抽象层,比如 saga?

0 投票
1 回答
82 浏览

c# - 设置新 saga 的初始状态

我们正在将遗留系统迁移到 nservicebus 5.0。将我们的业务数据迁移到 saga 数据的最佳方式通常是什么?例如,如果我们有一个 OrderCancellationPolicy saga,它只允许在 2 天内取消,那么来自遗留系统的过去订单如何以正确的状态创建这些新的 saga?

我看到两个选项。首先是编写一些 sql 脚本来预填充 saga 持久性表(我们使用的是 nhibernate 持久性)。另一种是创建某种特殊的导入消息,例如 MigrateOrderDataCmd,其中包含来自旧订单的数据。导入脚本可以发送 saga 可以处理的这些消息,并以这种方式设置 saga 数据。

对此领域的任何指导表示赞赏。