zilverline / sequent

CQRS & event sourcing framework for Ruby
https://www.sequent.io
MIT License
541 stars 58 forks source link

Introduce autoregistering command and event handlers #393

Closed lvonk closed 10 months ago

lvonk commented 11 months ago

Setting up (large) Sequent configs can become quite tedious since all CommandHandlers and EventHandlers need to be configured explicitly.

By setting enable_autoregistration to true this will no longer be needed and all Sequent::CommandHandlers, Sequent::Projectors and Sequent::Workflows not marked as abstract_class or skip_autoregister are appended to already configured command_handlers and event_handlers.

To use:

Add the following code to the sequent initializer:

Sequent.configure do |config|
  config.enable_autoregistration = true
end

Note for Rails users: In order for this to work Sequent will eager load all code before Sequent initializer runs since otherwise the command_handlers and event_handlers are still empty after initialization since normally eager_loading runs after all initializers ran.

This might cause other issues if initializers after sequents initializer depend on the fact the code is not eager loaded yet. If that is the case ensure that the Sequent initializer runs last.

This change will require a major version bump as we have introduced (some small) breaking changes.

TODO:

lvonk commented 10 months ago

@bforma would you mind giving this a test run before we merge this in? All works in our apps

bforma commented 10 months ago

I've tested this and can report the following:

Stekker(development):001:0> Sequent.configuration.command_handlers
[
    [0] #<Sequent::Core::AggregateSnapshotter:0x000000029b45c1d8>,
    [1] #<Imbalance::PTUCommandHandler:0x000000029b45c138>
]

Stekker(development):002:0> Sequent.configuration.event_handlers
[
    [0] #<Imbalance::PTUProjector:0x000000029b45bc10 @persistor=#<Sequent::Core::Persistors::ActiveRecordPersistor:0x000000029b45bb48>>,
    [1] #<SmartCharging::ExecuteEngineWorkflow:0x000000029b45b0a8>
]

When running the same two commands in our Rails console on master I see this:

Stekker(development):001:0> Sequent.configuration.command_handlers
[
    [0] #<Imbalance::PTUCommandHandler:0x000000016a690620>
]

Stekker(development):002:0> Sequent.configuration.event_handlers
[
    [0] #<Imbalance::PTUProjector:0x000000016a81e618 @persistor=#<Sequent::Core::Persistors::ActiveRecordPersistor:0x000000016a81e578>>,
    [1] #<SmartCharging::ExecuteEngineWorkflow:0x000000016a81ce08>
]

The difference seems that Sequent::Core::AggregateSnapshotter is now also automatically registered as a "command handler". Is that what we want/need?

Great to see this feature being implemented, thanks!

lvonk commented 10 months ago

Yes the Sequent::Core::AggregateSnapshotter is automatically registered if you set enable_autoregistration = true. Imo this makes sense otherwise you still need to manually register if you use snapshotting and have enable_autoregistration enabled. It can do no harm if you don't execute these commands.

The breaking changes with regards to cache_event_types are documented on the CHANGELOG (this will be a major release because of it).

Thanks a lot for testing!