Module: Servus::Events::Emitter
Overview
Provides event emission DSL for service objects.
This module adds the emits class method to services, allowing them to
declare events that will be automatically emitted on success, failure, or error.
Constant Summary collapse
- EMISSION_TRIGGERS =
Triggers accepted by the
emitsDSL.:successand:failureare selected from the service's result aftercallreturns.:error!is fired by Base#error! immediately before it raises, so it never coincides with:failure.Note the bang on
:error!— it mirrors the method that triggers it. %i[success failure error!].freeze
Class Method Summary collapse
-
.emit_result_events!(instance, result) ⇒ void
private
Emits events for a service result.
Instance Method Summary collapse
-
#build_event_payload(emission, result) ⇒ Hash
private
Builds the event payload using the configured payload builder or defaults.
-
#emission_condition_met?(emission, result) ⇒ Boolean
private
Returns true when all declared conditions on the emission pass.
-
#emit_events_for(trigger, result) ⇒ void
private
Emits events for a specific trigger with the given result.
-
#evaluate_emission_condition(condition, result) ⇒ Object
private
Evaluates a single emission condition — either a Proc/lambda or a Symbol method reference.
-
#require_event_schema!(event_name) ⇒ void
private
Enforces Config#require_event_payload_schema for an event that has no Event class to carry a schema.
-
#validate_event_payload!(event_name, payload) ⇒ void
private
Validates the payload against the Event class's schema registered for the event.
Class Method Details
.emit_result_events!(instance, result) ⇒ void
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.
This method returns an undefined value.
Emits events for a service result.
Called automatically after service execution completes. Determines the trigger type based on the result and emits all configured events.
36 37 38 39 |
# File 'lib/servus/events/emitter.rb', line 36 def self.emit_result_events!(instance, result) trigger = result.success? ? :success : :failure instance.send(:emit_events_for, trigger, result) end |
Instance Method Details
#build_event_payload(emission, result) ⇒ Hash
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.
Builds the event payload using the configured payload builder or defaults.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/servus/events/emitter.rb', line 236 def build_event_payload(emission, result) builder = emission[:payload_builder] if builder.is_a?(Proc) instance_exec(result, &builder) elsif builder.is_a?(Symbol) # Method-based payload builder send(builder, result) elsif result.success? # Default for success: return data result.data else # Default for failure/error: return error result.error end end |
#emission_condition_met?(emission, result) ⇒ Boolean
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 true when all declared conditions on the emission pass.
173 174 175 176 177 178 179 180 181 |
# File 'lib/servus/events/emitter.rb', line 173 def emission_condition_met?(emission, result) if_condition = emission[:if_condition] unless_condition = emission[:unless_condition] return false if if_condition && !evaluate_emission_condition(if_condition, result) return false if unless_condition && evaluate_emission_condition(unless_condition, result) true end |
#emit_events_for(trigger, result) ⇒ void
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.
This method returns an undefined value.
Emits events for a specific trigger with the given result.
155 156 157 158 159 160 161 162 163 |
# File 'lib/servus/events/emitter.rb', line 155 def emit_events_for(trigger, result) self.class.emissions_for(trigger).each do |emission| next unless emission_condition_met?(emission, result) payload = build_event_payload(emission, result) validate_event_payload!(emission[:event_name], payload) Servus::Events::Bus.emit(emission[:event_name], payload) end end |
#evaluate_emission_condition(condition, result) ⇒ Object
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.
Evaluates a single emission condition — either a Proc/lambda or a Symbol method reference.
Both forms receive the result object so conditions can inspect result.data, result.error, result.success?, etc.
192 193 194 |
# File 'lib/servus/events/emitter.rb', line 192 def evaluate_emission_condition(condition, result) condition.is_a?(Proc) ? instance_exec(result, &condition) : send(condition, result) end |
#require_event_schema!(event_name) ⇒ void
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.
This method returns an undefined value.
Enforces Config#require_event_payload_schema for an event that has no Event class to carry a schema.
An unregistered event name is the one case where a payload cannot be validated at all, so it is exactly where the flag matters most. Skipping it here would mean the setting silently passed over the events furthest from having a contract.
222 223 224 225 226 227 228 |
# File 'lib/servus/events/emitter.rb', line 222 def require_event_schema!(event_name) return unless Servus.config.require_event_payload_schema raise Servus::Support::Errors::SchemaRequiredError, "#{self.class} emits :#{event_name} but no Event class is registered for it — " \ 'schema missing! require_event_payload_schema is set to true.' end |
#validate_event_payload!(event_name, payload) ⇒ void
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.
This method returns an undefined value.
Validates the payload against the Event class's schema registered for the event.
203 204 205 206 207 208 |
# File 'lib/servus/events/emitter.rb', line 203 def validate_event_payload!(event_name, payload) event_class = Servus::Events::Bus.event_for(event_name) return require_event_schema!(event_name) unless event_class Servus::Support::Validator.validate_event_payload!(event_class, payload) end |