Hi everyone. Very excited to try and use axon as main billing platform as replacement to current.
Currently have some concerns due to project specifics.
At a high level view, there are lots of users that are charged by milliseconds interval.
Publishing axon command for each such event I believe is an overkill. But batching them for
too long is not acceptable either ( will be lag in current balance ). So I’ve tried to find a middle-ground here by using kafka
and storing all those micro charges there. Each minute I’m retrieving everything from it, batch and only then publish to axon.
Root aggregate in my case is a user, so when everything is consumed I have lots charge commands, one for each user.
Problem that concerns me is that not all of dispatched commands might be handled successfully by projection handlers.
Also I believe there might be some external problems(i.e network) saving those events to axon. In such cases I don’t wan’t
to commit kafka offsets, just rollback everything.
Found thread with similar problem: https://groups.google.com/forum/#!topic/axonframework/M8SlGXsUsjM
The way to address this problem there was to use BatchCommand and SpringTransactionManager.
Planning to try this out and see how it goes, but what bothers me is this solution looks hacky )
Probably I’m missing something and there is more elegant way to achieve what I’m after ?
Would be glad to hear any advices / thoughts. Thanks!
Let’s discuss your requirements before we jump into some conclusion here.
From your explanation I can deduce that there is a User aggregate. How many commands you are expecting for a specific User in a second? We want to make sure that you can scale your command side by applying "axon command for each such event" . Maybe it is not an overkill at all, and it is the best design by my opinion.
How many commands you are expecting for a specific User in a second?
Lets say on average 100 commands per user each second and there will be lots of users, lets say 100 again.
This number is changing and depends on lots of factors: it could be active user or not, we could decide to scale, so more nodes are sending
this commands. Ideally it would be great to separate those factors from axon, so that it gets constant amount of load.
Thats why I’ve decided to use some buffer (kafka). I’ve already implemented some tests using batch command and batch command handler aggregate
but it looks too clunky for me
Thanks a lot for the replay performance tuning article.
Lots of useful tips. Especially Batch optimization paragraph. Maybe there are some examples how to explicitly specify a unit of work for related events ? Not clear enough how to achieve batching behavior using unit of work. ( My first assumption is to aggregate changes from events in UnitOfWork.resource map and then add UnitOfWork.onCommit() handler to simply make one update using results in resource)
Also, is it possible to use one unit of work for multiple commands without batch command ? Couldn’t find a way to pass unit of work to command bus or command gate away.
I’ve thought a little a decided to stick to your first reply: scale query side separately.
If something bad happens at projecting side - I’ll always be able to restore them. Using replay tunings really helps a lot.
If something bad happened with axon itself, well there is not much to be done in that case until problem is resolved.
Configuring flow control of axon server bus or using disruptor bus looks promising, but wan’t to keep first iteration simple and look how it goes.
Thanks a lot for the help Ivan !