Class: Servus::EventHandler
- Inherits:
-
Object
- Object
- Servus::EventHandler
- Defined in:
- lib/servus/event_handler.rb
Overview
Base class for event handlers that map events to service invocations.
EventHandler classes live in app/events/ and use a declarative DSL to
subscribe to events and invoke services in response. Each handler
subscribes to a single event via the handles method.
Class Attribute Summary collapse
-
.event_name ⇒ Symbol?
readonly
Returns the event name this handler is subscribed to.
-
.payload_schema ⇒ Hash?
readonly
private
Returns the payload schema.
Class Method Summary collapse
-
.emit(payload) ⇒ void
Emits the event this handler is subscribed to.
-
.handle(payload) ⇒ Array<Servus::Support::Response>
Handles an event by invoking all configured services.
-
.handles(event_name) ⇒ void
Declares which event this handler subscribes to.
-
.invocations ⇒ Array<Hash>
Returns all service invocations declared for this handler.
-
.invoke(service_class, options = {}) {|payload| ... } ⇒ void
Declares a service invocation in response to the event.
-
.schema(payload: nil) ⇒ void
Defines the JSON schema for validating event payloads.
-
.validate_all_handlers! ⇒ void
Validates that all registered handlers subscribe to events that are actually emitted by services.
Class Attribute Details
.event_name ⇒ Symbol? (readonly)
Returns the event name this handler is subscribed to.
47 48 49 |
# File 'lib/servus/event_handler.rb', line 47 def event_name @event_name end |
.payload_schema ⇒ Hash? (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the payload schema.
123 124 125 |
# File 'lib/servus/event_handler.rb', line 123 def payload_schema @payload_schema end |
Class Method Details
.emit(payload) ⇒ void
This method returns an undefined value.
Emits the event this handler is subscribed to.
Provides a type-safe, discoverable way to emit events from anywhere in the application (controllers, jobs, rake tasks) without creating a service.
150 151 152 153 154 155 156 |
# File 'lib/servus/event_handler.rb', line 150 def emit(payload) raise 'No event configured. Call handles :event_name first.' unless @event_name Servus::Support::Validator.validate_event_payload!(self, payload) Servus::Events::Bus.emit(@event_name, payload) end |
.handle(payload) ⇒ Array<Servus::Support::Response>
Handles an event by invoking all configured services.
Iterates through all declared invocations, evaluates conditions, maps the payload to service arguments, and invokes each service.
168 169 170 171 172 173 174 |
# File 'lib/servus/event_handler.rb', line 168 def handle(payload) invocations.map do |invocation| next unless should_invoke?(payload, invocation[:options]) invoke_service(invocation, payload) end.compact end |
.handles(event_name) ⇒ void
This method returns an undefined value.
Declares which event this handler subscribes to.
This method registers the handler with the event bus and stores the event name for later reference. Each handler can only subscribe to one event.
37 38 39 40 41 42 |
# File 'lib/servus/event_handler.rb', line 37 def handles(event_name) raise "Handler already subscribed to :#{@event_name}. Cannot subscribe to :#{event_name}" if @event_name @event_name = event_name Servus::Events::Bus.register_handler(event_name, self) end |
.invocations ⇒ Array<Hash>
Returns all service invocations declared for this handler.
93 94 95 |
# File 'lib/servus/event_handler.rb', line 93 def invocations @invocations || [] end |
.invoke(service_class, options = {}) {|payload| ... } ⇒ void
This method returns an undefined value.
Declares a service invocation in response to the event.
Multiple invocations can be declared for a single event. Each invocation requires a block that maps the event payload to the service's arguments.
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/servus/event_handler.rb', line 79 def invoke(service_class, = {}, &block) raise ArgumentError, 'Block required for payload mapping' unless block @invocations ||= [] @invocations << { service_class: service_class, options: , mapper: block } end |
.schema(payload: nil) ⇒ void
This method returns an undefined value.
Defines the JSON schema for validating event payloads.
115 116 117 |
# File 'lib/servus/event_handler.rb', line 115 def schema(payload: nil) @payload_schema = payload.with_indifferent_access if payload end |
.validate_all_handlers! ⇒ void
This method returns an undefined value.
Validates that all registered handlers subscribe to events that are actually emitted by services.
Checks all handlers against all service emissions and raises an error if any handler subscribes to a non-existent event. Helps catch typos and orphaned handlers.
Respects the Servus.config.strict_event_validation setting - skips validation if false.
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/servus/event_handler.rb', line 188 def validate_all_handlers! return unless Servus.config.strict_event_validation emitted_events = collect_emitted_events orphaned = find_orphaned_handlers(emitted_events) return if orphaned.empty? raise Servus::Events::OrphanedHandlerError, "Handler(s) subscribe to non-existent events:\n" \ "#{orphaned.map { |h| " - #{h[:handler]} subscribes to :#{h[:event]}" }.join("\n")}" end |