如何获得有关 CQRS 更改的即时反馈
How to get instant feedback on a change in CQRS
假设我有下一个伪代码来在我的 WebApi 项目中根据 CQRS(实际上,事件源也有问题)实现基于命令的更改:
public IHttpActionResult ChangeVendor(ChangeVendorModel changeModel)
{
/* 1 */ // user input validation
/* 2 */ var changeCommand = changeModel.MapTo<ChangeVendorCommand>();
/* 3 */ bus.Send(changeCommand); // start the change processing
/* 4 */ return Ok();
}
解释:
- 我们执行基本的用户输入验证(作为字符串长度或仅
正数)但不是业务验证(因为该供应商是
在黑名单中)。
- 我们将输入模型转换为总线命令。
- 我们通过总线发送准备好的变更命令进行处理。
- 我们的意思是更改已应用并且域模型是
可用于进一步操作。
题目:
一个。总线处理是异步的。我如何确定(在第 4 步之后)
我的更改已应用并且应用已准备好呈现成功
显示数据库中已更改记录的视图,专为
查询目的?
b。假设发生了记录版本冲突(数据违规)或模型未通过业务规则(域违规)。我怎样才能立即从总线上通知用户这件事? 在一个设计糟糕的系统中,用户可能会看到成功的结果,因为我们成功地安排了总线上的更改,稍后他们会在尝试应用实际更改时看到带有错误的通知。
正如我在评论中建议的那样,您可以等待表示完成的事件,并且在收到时仅 return 向用户发送信号。一些伪代码:
public IHttpActionResult ChangeVendor(ChangeVendorModel changeModel)
{
var changeCommand = changeModel.MapTo<ChangeVendorCommand>();
bus.Send(changeCommand); // start the change processing
var replyReceived=false;
bool success = false;
while(!replyreceived)
{
Task vendorChanged = Task.Factory.StartNew(()=>
{
var reply=bus.Receive<VendorChanged>());
if(reply.CorrelationToken==changeCommand.CorrelationToken)
{
replyReceived=true;
success=true;
}
},SomeTimeout);
Task vendorChangedFailed = Task.Factory.StartNew(()=>
{
var reply=bus.Receive<VendorChangeFailed>());
if(reply.CorrelationToken==changeCommand.CorrelationToken)
{
replyReceived=true;
success=false;
}
},SomeTimeout());
Task.WaitAny(new Task[]{vendorChanged,vendorChangeFailed});
}
if(success)
{
return Ok();
}
else
{
return ChangeVendorFailed();
}
}
显然接收需要在其自己的订阅上,以确保它不会接受其他实例的回复,并且您可以创建订阅以仅接收具有正确关联令牌或其他标识的消息 属性,但这给了你一些想法来给这只猫换皮,让你的任务异步工作流看起来对用户来说是同步的
假设我有下一个伪代码来在我的 WebApi 项目中根据 CQRS(实际上,事件源也有问题)实现基于命令的更改:
public IHttpActionResult ChangeVendor(ChangeVendorModel changeModel)
{
/* 1 */ // user input validation
/* 2 */ var changeCommand = changeModel.MapTo<ChangeVendorCommand>();
/* 3 */ bus.Send(changeCommand); // start the change processing
/* 4 */ return Ok();
}
解释:
- 我们执行基本的用户输入验证(作为字符串长度或仅 正数)但不是业务验证(因为该供应商是 在黑名单中)。
- 我们将输入模型转换为总线命令。
- 我们通过总线发送准备好的变更命令进行处理。
- 我们的意思是更改已应用并且域模型是 可用于进一步操作。
题目:
一个。总线处理是异步的。我如何确定(在第 4 步之后) 我的更改已应用并且应用已准备好呈现成功 显示数据库中已更改记录的视图,专为 查询目的?
b。假设发生了记录版本冲突(数据违规)或模型未通过业务规则(域违规)。我怎样才能立即从总线上通知用户这件事? 在一个设计糟糕的系统中,用户可能会看到成功的结果,因为我们成功地安排了总线上的更改,稍后他们会在尝试应用实际更改时看到带有错误的通知。
正如我在评论中建议的那样,您可以等待表示完成的事件,并且在收到时仅 return 向用户发送信号。一些伪代码:
public IHttpActionResult ChangeVendor(ChangeVendorModel changeModel)
{
var changeCommand = changeModel.MapTo<ChangeVendorCommand>();
bus.Send(changeCommand); // start the change processing
var replyReceived=false;
bool success = false;
while(!replyreceived)
{
Task vendorChanged = Task.Factory.StartNew(()=>
{
var reply=bus.Receive<VendorChanged>());
if(reply.CorrelationToken==changeCommand.CorrelationToken)
{
replyReceived=true;
success=true;
}
},SomeTimeout);
Task vendorChangedFailed = Task.Factory.StartNew(()=>
{
var reply=bus.Receive<VendorChangeFailed>());
if(reply.CorrelationToken==changeCommand.CorrelationToken)
{
replyReceived=true;
success=false;
}
},SomeTimeout());
Task.WaitAny(new Task[]{vendorChanged,vendorChangeFailed});
}
if(success)
{
return Ok();
}
else
{
return ChangeVendorFailed();
}
}
显然接收需要在其自己的订阅上,以确保它不会接受其他实例的回复,并且您可以创建订阅以仅接收具有正确关联令牌或其他标识的消息 属性,但这给了你一些想法来给这只猫换皮,让你的任务异步工作流看起来对用户来说是同步的