我正在使用 CQRS 隔离,对于事务命令或从一个节点到远程节点的请求响应非常有效。
我有一个用例,其中将向远程节点发出命令,这将产生“流”数据(很像正在运行的远程命令,服务器在运行过程中以文本形式向我们提供更新):
// this is sent from requesting node to remote node to initiate the stream
public class LongRunningCommand: ICommand
{
Guid Session { get; set; } // the session ID to use
string CommandLine {get; set; } // the command the remote note will run
}
然后,该数据在一段时间内以多个数据包的形式从远程节点发送到请求节点:
// this is sent from remote node to requestor in multiple updates over time
public class UpdateProgress: ICommand
{
Guid Session { get; set; } // possibility to multiplex sessions
int Sequence { get; set; } // de-dupe/resequencing out of order packets (lower QOS)
byte[] Payload { get; set; } // the data to be passed to the application
}
这并不是一个真正的命令,也不是一个请求-回复(因为有多个回复)——它是一个长时间运行的 session ,但我不确定这如何与 CQRS 相适应。
订购此产品的最佳方式是什么?我的请求节点是否可以有一个如下所示的命令处理程序(其中 UpdateProgress
是正在处理的“命令”):
public class UpdateProgressCommandHandler : ICommandHandler<UpdateProgress>
{
public async Task HandleAsync(UpdateProgress message)
{
// resequence in handler or chained infrastructure - omitted for brevity
var window = GetWindowForSession(message.Session);
var updateFromServer = System.Text.Encoding.UTF8.GetString(message.Payload);
await window.WriteLine(updateFromServer);
}
}
上面的方法有效(我认为相当不错),但术语似乎有点时髦(命令名称 UpdateProgress 更像是一个事件而不是命令)。
或者我最好放弃命令/查询的概念,并进入完整的事件总线,如果我这样做,我将如何处理初始请求,因为这不是一个事件,它更多的是一个命令(这不会在处理事件的事件总线上在语义上没有意义 - 而不是命令或查询)。或者我只是陷入命名约定中?由于第一次这样做,请欣赏上述用例的最佳实践 View 。
最佳答案
我不确定我是否理解正确,需要与远程节点通信的命令
似乎不属于您的域的一部分。这并不是说它不是一个Command
,您仍然可以将其定义为Command
,但不能在您的Domain
IMO 中定义。您可以在此处查看集成事件。
在没有完全了解您的领域的情况下,您可以按照以下方式定义流程:
执行命令来修改您的域(例如
状态:待处理
)将集成事件从 CommandHandler 引发到单独的工作线程/服务总线
单独的工作人员完成该过程,然后引发另一个集成事件
您的工作人员订阅该事件并更新您域的相关部分(例如
状态:已完成
)。
关于c# - 用于流数据的 CQRS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60581395/