-
Notifications
You must be signed in to change notification settings - Fork 7
Command execution
##Overview GridDomain supports command execution in two modes: fully asynchronous non-blocking and synchronous, waiting for given event by timeout. In both cases interface IGridDomainNode is used. ###Command asynchronous execution Common way to execute commands is fire-and forget
var command = new CreateOrderCommand(orderNum);
GridNode.Execute(command);
//add any waiting here
var order = LoadAggregate<OrderAggregate>(command.OrderId);
Assert.AreEqual(command.OrderNum, order.Num);
We are not waiting and command is processed asynchronously, on different thread or machine. We don't know how much time command execution will take, and we don't wait for command faults.
Command results can be obtained only from read model after some period of time. Any command fault will be ignored. You can find example in unit test
###Command execution with confirmation
GridDomain can execute commands and wait for some confirmation by answer message.It can be any message GridDomain can produce: domain event, notification,fault.
Confirmed command execution needs additional information about expecting answer. It is stored in ExpectedMessage class. ExpectedMessage instance can be created by constructor or by one of static factory methods . If we are interesting in waiting for a fault, ExpectedFault should be used.
Having ExpectedMessage and declaring Timeout, you can execute command following way:
var command= new CreateOrderCommand(orderNumber);
var expectedMessage = ExpectedMessage.Once<OrderCreated>(e => e.SourceId, command.OrderId);
var evt = GridNode.Execute(command,Timeout,expectedMessage);
In this example we are blocking processing thread until receive of OrderCreated message produced by our command. Such waiting is usefull when we want to wait for read model rebuild, or some notification to proceed futher. Also it can be used in cases when we need to issue many commands in particular order.
IGridDomain node have a lot of extension methods for different kinds of command execution with confirmation, you can find them here with usage detailed examples
Fault is an error occurred in some processor while handling message. It is represented by IFault interface.
If command is executed with confirmation, GridDomainNode will deliver faults to caller and try to raise initial exception, keeping stack trace of exception.
By default any exception occurred in aggregate while command execution will be returned as fault. Also it is possible to return faults from custom message handlers. For this we need to pass additional ExpectedFault instance to execute method. ExpectedFault is ExpectedMessage with additional ProcessMessageType field to store information about message will be processed in custom message handler.
After command is executed, any number of custom message handlers can be activated. By default any fault from them will be treated as error and passed back to command execution initiator. We can specify type of exact message handler to treat exceptions from it as command execution errors. Common case for it is making sure read model was rebuild after command execution, and get an error if not.
Next example is showing execution of command with waiting for readmodel build or error from aggregate or projection builder
var command= new CreateOrderCommand(orderNumber);
var expectedFault = Expect.Fault<OrderCreated>(e => e.SourceId, command.OrderId, typeof(OrderProjectionBuilder));
var expectedMessage = Expect.Message<OrderCreatedNotification>(e => e.SourceId, command.OrderId);
var evt = GridNode.Execute(command,Timeout,expectedMessage, expectedFault);
You can add several source types of faults by adding them to Expect.Fault parameters:
var command= new CreateOrderCommand(orderNumber);
var expectedFault = Expect.Fault<OrderCreated>(e => e.SourceId,
command.OrderId,
typeof(OrderProjectionBuilder),
typeof(OrderCreatedNotificationMailSender));
var expectedMessage = Expect.Message<OrderCreatedNotification>(e => e.SourceId, command.OrderId);
var plan = new CommandPlan(command, Timeout, expectedFault, expectedMessage);
var evt = GridNode.Execute<OrderCreatedNotification>(plan).Result;