Module: RubyPi::Agent::EventEmitter

Included in:
Core
Defined in:
lib/ruby_pi/agent/events.rb

Overview

Mixin that adds event subscription and emission to any class. Include this module and call on, emit, and off to wire up event-driven communication between components.

Examples:

Using EventEmitter in a class

class MyService
  include RubyPi::Agent::EventEmitter
end

svc = MyService.new
svc.on(:text_delta) { |data| puts data[:content] }
svc.emit(:text_delta, content: "Hello")

Instance Method Summary collapse

Instance Method Details

#emit(event, data = {}) ⇒ void

This method returns an undefined value.

Fires all handlers registered for the given event type. Each handler receives the data hash as its argument. Handlers that raise are rescued individually — one failing handler does not prevent others from executing.

If a handler raises during a non-error event, the error is re-emitted as an :error event so subscribers can observe it. To prevent infinite recursion, errors raised inside :error event handlers are silently swallowed — they are not re-emitted. This ensures that a broken error handler cannot crash the agent loop.

Parameters:

  • event (Symbol)

    the event type to fire

  • data (Hash) (defaults to: {})

    arbitrary payload passed to each handler



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ruby_pi/agent/events.rb', line 87

def emit(event, data = {})
  validate_event!(event)
  event_handlers[event].each do |handler|
    handler.call(data)
  rescue StandardError => e
    # Guard against infinite recursion: if we are already emitting an
    # :error event and the error handler itself raises, we must not
    # re-emit — that would cause unbounded recursion. Silently discard
    # the secondary error instead.
    if event != :error
      emit(:error, error: e, source: :event_handler, event: event)
    end
  end
end

#off(event, &block) ⇒ Proc?

Removes a specific handler from an event's subscriber list. If the handler is not found, this is a no-op. Pass the same block reference that was given to on.

Parameters:

  • event (Symbol)

    the event type to unsubscribe from

  • block (Proc)

    the handler to remove

Returns:

  • (Proc, nil)

    the removed handler, or nil if not found



109
110
111
112
# File 'lib/ruby_pi/agent/events.rb', line 109

def off(event, &block)
  validate_event!(event)
  event_handlers[event].delete(block)
end

#on(event, &block) ⇒ Proc

Subscribes a handler block to a specific event type. The block will be called every time emit fires for that event. Multiple handlers can be registered for the same event — they are invoked in the order they were registered.

Parameters:

  • event (Symbol)

    the event type to subscribe to (must be in EVENTS)

  • block (Proc)

    the handler to invoke when the event fires

Returns:

  • (Proc)

    the registered handler block, for later removal via off

Raises:

  • (ArgumentError)

    if the event type is not in EVENTS



67
68
69
70
71
# File 'lib/ruby_pi/agent/events.rb', line 67

def on(event, &block)
  validate_event!(event)
  event_handlers[event] << block
  block
end