Hi Allard and all.
I’m working with Axon for our production system (not a POC anymore) and even if sometimes I see clearly what to do more often than not I’m still puzzled and baffled. A simple implementation of a simple aggregate looks clear, but when a aggregate has to interact with other parts of the system things get complicated.
My Task aggregate currently has something like this:
`
@CommandHandler
public void handle(StartTaskCommand command) {
boolean ok = userService.checkUserPermissions(command.getOwner(), this.task);
if(ok){
apply(new TaskStartedEvent(…));
}else{
apply(new TaskStartedFailedEvent(…));
}
}
@EventSourcingHandler
public void on(TaskStartedEvent event) throws Exception {
task.setState(TaskState.IN_PROGRESS);
}
@EventSourcingHandler
public void on(TaskStartedFailedEvent event) throws Exception {
task.setState(TaskState.FAILED);
}
`
1 command, 2 events…
So far so good. But if that checkUserPermissions is actually some more complicated thing that interacts to the world, what do I do? Using a Saga I will have to do something like:
`
@CommandHandler
public void handle(StartTaskCommand command) {
apply(new TaskStartingEvent(…));
}
@EventSourcingHandler
public void on(TaskStartingEvent event) throws Exception {
task.setState(TaskState.STARTING);
}
@EventSourcingHandler
public void on(TaskStartedEvent event) throws Exception {
task.setState(TaskState.IN_PROGRESS);
}
@EventSourcingHandler
public void on(TaskStartedFailedEvent event) throws Exception {
task.setState(TaskState.FAILED);
}
`
1 command, 3 events…
Plus the saga:
`
@SagaEventHandler(associationProperty = “taskId”)
public void handle(TaskStartingEvent event) {
ComplicatedCommand command = new ComplicatedCommand(event.getId());
commandGateway.send(command);
}
@SagaEventHandler(associationProperty = “taskId”)
public void handle(ComplicatedThingFailed event) {
TaskFailStartCommand command = new TaskFailStartCommand(event.getId(), event.getReason());
commandGateway.send(command);
}
@SagaEventHandler(associationProperty = “taskId”)
public void handle(ComplicatedThingSucceeded event) {
TaskContinueStartCommand command = new TaskContinueStartCommand(event.getId(), event.getReason());
commandGateway.send(command);
}
`
So now in my Aggregate I have to add 2 more commands
TaskFailStartCommand
TaskContinueStartCommand (???)
giving 3 commands + 3 events to do only one thing… Considering the HumanTask specification has more than 50 commands of which I pretend to use at least 16, using this structure I will have 16 commands * 3 + 16 events * 3, total 96 on the Aggregate only!!! On the Saga I will have 1 command + 2 events + 1 timeout for each call I want to make to the “outside world”… or use sync calls instead, but that defeats the purpose of Sagas.
Does this sounds right to you? I know this is more a rant than a question, but I’m a bit lost here…
Thanks.