Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Q: Make self subscribing Objects in rails, Class load issues #716

Closed
kinnrot opened this issue Mar 19, 2020 · 3 comments
Closed

Q: Make self subscribing Objects in rails, Class load issues #716

kinnrot opened this issue Mar 19, 2020 · 3 comments

Comments

@kinnrot
Copy link

kinnrot commented Mar 19, 2020

Looking for a guidance,

In general I think that an event handler should be responsible for subscribing itself to an event, For example:

  class FooHandler

      Rails.config.event_store.subscribe(to:[FooHappened]) do |event|

      # Fooing whatever...

    end

    end

It can also be a reference to instance method instead of block..

Either way, No one is referencing this class ever, and I want the subscription to occur after the event store is initialized, but keeping things separated. Tried autoloading but it messed up my name spacing.

Is there a best practice here? maybe all should include a base module and reflect on all classes that included this module or something ? is that possible?

thanks

@joelvh
Copy link
Contributor

joelvh commented Mar 19, 2020

@kinnrot I've done something like this. I created some "DSL" classes on top of RES to maintain handler classes that subscribe to events. I also built in tracking with all the classes involved to generate a graphviz relationship diagram.

I've been meaning to get something into contrib - previous conversation about this is in #665.

My approach is pretty simple, to achieve what you're talking about. Some sample code from my application below...

The on method in the base class that my handler classes inherit from (e.g. class UserHandler < BaseHandler):

def on(*message_classes, **options, &block)
  options = self.handler_options.merge(options)
  options[:to] ||= block

  message_classes.each do |message_class|
    HandlerRegistry.register(self, message_class, callback, options)
  end
end

The handler registry does this, which basically stores the information in a Registration struct:

def register(host_class, message_class, callback, options)
  registrations << Registration.new(host_class, callback, message_class, options)
end

Then subscribe registered handlers:

event_store = Container['event_store.client']
types = %i[denormalizers aggregators notifiers]
not_subscribed = []

MyApp.bounded_contexts.each do |bounded_context|
  types.each do |type|
    bounded_context.__send__(type).each do |handler_class|
      handler_class.handlers.each do |handler|
        event_store.subscribe(handler.callback, to: [handler.message_class])
      end
    end
  end

  not_subscribed += types.reduce(bounded_context.event_handlers.map(&:handlers)) do |handlers, type|
    handlers - bounded_context.__send__(type).map(&:handlers)
  end
end

### Handle remaining event handlers

not_subscribed.each do |handler|
  event_store.subscribe(handler.callback, to: [handler.message_class])
end

Not sure if that's what you're looking for at the moment, but I prefer a DSL that is more succinct and doesn't expose internal dependencies so much like RES.

@joelvh
Copy link
Contributor

joelvh commented Mar 19, 2020

I should note that my project is using rom-rb and leveraging much of dry-rb, such as the "container" that registers my global things. They have some tools like dry-system that help organize application code that needs to be "booted", such as building out your handlers in one step and then registering the subscriptions in another, etc.

@kinnrot
Copy link
Author

kinnrot commented Mar 23, 2020

@joelvh thanks, This is what I'm looking for, hoping to find a simpler, dependency free approach if possible.

@RailsEventStore RailsEventStore locked and limited conversation to collaborators Sep 7, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants