Replaying events

Hej,
I am continue’ing my testing of Axon and would like to replay events. However i am running into the problem that i can’t find any documentation/example on how to do this in Axon3. Maybe i am looking in the wrong place? It seems some documentation mentions the ReplayAware interface, that doesn’t exist anymore. I have also seem some mentions of the TrackingEventProcessor but I can’t seem to find much information about it?

I would also like to implement a projection that is calculated at runtime. For example i would like it to return all items that have been created in the last x days. I figure event sourcing should be really well at this, as i would just replay the events and only keep the created events that are younger then 7 days. Would this something to be done with the replay mechanism as well?

Thanks for pointing me in the right direction, it has been really fun messing with the framework.

Hi Geert,

the documentation still refers to Axon 2 for the most part. Axon 3 reference guide is in progress.

For a replay, you will need to use a TrackingProcessor. By default, Axon will use a SubscribingProcessor for your event handlers.
Do you use Spring or “plain java” configuration? You will need to specify that you want to have a tracking processor instead. In M5 that was all but trivial, unfortunately. A fix to make that easier has already been committed and will be available in the next release.

Once you have a TrackingProcessor, it will use a TokenStore to store a reference to the events it has processed (a so-called Token). Since it has no token in the beginning, it will start tracking the event store from the beginning. To force a replay, simply remove the token for a specific TrackingProcessor from the database, and it starts all over again.

Cheers,

Allard

Hej,

I am using spring.

Is it possible when you are reply’ing event to only use certain listeners? This would come in handy for my example where i want to calculate all items that have been created the last x days. I don’t want my other projections to be impacted.
I would also like to do this stuff at ‘run time’. What i mean by that is that the user requests all items created for the last 5 days through a HTTP get request. An other user could be requesting all items created the last 7 days at the same time. So this would be a projection that is build at request time in memory. Is this something that would be possible?

AFAIU for this you can group eventhandlers into clusters http://www.axonframework.org/docs/2.4/single.html#d5e1853

Jorg

That part of the documentation doesn’t seem to apply to version3 of axon

In Axon 3 you can use a TrackingEventProcessor to replay events on a group of event listeners. It uses a tracking token to keep track of its position in the event store. If its tracking token is null it will start replaying the entire event store to its event listeners.

However, I’m not sure this is the solution to your problem. As I understand your question you want to create projections through replay each time a query is done. Or do you intend to do this once per application run time? If it’s the former it will probably be more efficient to persist these projections.

Rene

It is the former, i want some very dynamic projections. The type that are hard to do in a more traditional CRUD application, but event sourcing should be super at it. Keep in mind that this is just a testing application, so they don’t all make sense either, they are just to see if they are possible.
I have an aggregate called TodoItem and this can be in 2 states Started and Finished. I want the user to be able to do queries like this:

  • Find all TodoItems that have been created in the last X days, where X is something the user can input.
  • Find all TodoItems that have been open longer then X days, where X is something the user can input.
  • Find all TodoItems that took longer then X days to be finished, where X is something the user can input.
  • Find all TodoItems that have been created between X and Y, where X and Y are provided by the user.

  • Most of these projections are hard to persist, as they depend on both user input and on temporal stuff. So i thought replay’ing the events when the query is done. Is this something for the TrackingEventProcessor, and also will it work correctly when multiple users are doing the query at the same time, possible with different parameters.

Hi Geert,

On demand replaying for query models can be very effective though usually mainly if these replays can be done from the events belonging to a single aggregate.

In your case you need your queries to be made across made against projections resulting from events of many different aggregates. Those type of queries are typically less helped by on demand replays as you’ll need to replay a considerable amount of events before you can respond to the queries.

In fact, the queries you mention actually sound ideally suited for more ‘traditional’ queries against existing (persisted) projections. All you need for the examples you mentioned are ‘todo item entries’ that contain the timestamp on which they were created and completed. A simple ‘select … from … where …’ statement should suffice and would definitely provide you further benefits. Even if this is just a test app, you still want to use patterns that you’d use in real life as well.

In any case, should you still want to replay for these queries then you could indeed use a TrackingEventProcessor with InMemoryTokenStore. Each time your app launches it will replay the entire event store and build your projections up in memory (and keep them in sync with newly published events). You could then query these in-memory projections.

That could be a way. Replaying the entire event store each time a single query is done is madness in this case imo :wink:

Best,

Rene

Hej,
True I guess i can have most of them as a seperate projection. Maybe i should rethink my approach. But as i want to go a bit spring cloud as well, i would like to have all/some of my projections as a seperate server. Any good tips on how to setup the distributed event store?

Hi Geert,

in the framework itself, there no distributed event store (yet). However, by specifying a StorageEngine that stores data in, for example, relational database, you can ‘share’ events between multiple nodes.

Alternatively, you could forward events on an AMQP message broker (or any other broker, for that matter). But that doesn’t give you the possibility to define the replaying capable TrackingEventProcessors.

Hope this helps.
Cheers,

Allard