palkan / active_event_store

Rails Event Store in a more Rails way
MIT License
181 stars 13 forks source link

Add support to classes that inherit from Class as async subscribers. #9

Closed caws closed 2 years ago

caws commented 2 years ago

What is the purpose of this pull request?

This PR adds support to classes that inherit from Class as async subscribers. More info can be found at #8

Much like what RES does when dispatching events to subscribers, in order to support classes that inherit from Class it is necessary to check if a given subscriber is a Class and if it does not contain a class method called #call.

If that asserts to true, the #call method must be invoked on an instance of the subscriber being passed, much like what RES does when dispatching events to subscribers (see here)

The specs contain a bit more context on this.

What changes did you make? (overview)

Instead of calling subscribe.call(event) directly, it now checks if subscriber is a Class and if it does not implement #call as a class method.

Before:

  class SubscriberJob < ActiveJob::Base
    ...
    def perform(payload)
      event = event_store.deserialize(**payload, serializer: ActiveEventStore.config.serializer)

      event_store.with_metadata(**event.metadata.to_h) do
          subscriber.call(event)
      end
    ...
    end
  end

After:

  class SubscriberJob < ActiveJob::Base
    ...
    def perform(payload)
      event = event_store.deserialize(**payload, serializer: ActiveEventStore.config.serializer)

      event_store.with_metadata(**event.metadata.to_h) do
        if subscriber.is_a?(Class) && !subscriber.respond_to?(:call)
          subscriber.new.call(event)
        else
          subscriber.call(event)
        end
      end
    ...
    end
  end

Is there anything you'd like reviewers to focus on?

Checklist