Module: Takagi::Hooks
- Defined in:
- lib/takagi/hooks.rb
Overview
Lightweight hook dispatcher used by the plugin system to observe internal events.
Hooks are intentionally simple: subscribe with a callable, emit with a hash payload. Errors in subscribers are caught and logged to avoid cascading failures.
Class Method Summary collapse
-
.emit(event, payload = {}) ⇒ Object
Emit an event with a payload hash to all subscribers.
- .event_bus_ready? ⇒ Boolean
- .hook_address(event) ⇒ Object
-
.subscribe(event, handler = nil) {|Hash| ... } ⇒ #call
Register a handler for a given event symbol.
-
.unsubscribe(event, handler) ⇒ Object
Remove a previously registered handler.
Class Method Details
.emit(event, payload = {}) ⇒ Object
Emit an event with a payload hash to all subscribers.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/takagi/hooks.rb', line 49 def emit(event, payload = {}) if event_bus_ready? Takagi::EventBus.publish(hook_address(event), payload, freeze_body: false, scope: Takagi::EventBus::Scope::LOCAL) else handlers = @mutex.synchronize { @subscribers[event].dup } return if handlers.empty? handlers.each do |handler| handler.call(payload) rescue StandardError => e begin Takagi.logger.warn("Hook #{event} handler error: #{e.}") rescue StandardError # Logger may not be initialized yet; swallow errors silently. end end end end |
.event_bus_ready? ⇒ Boolean
72 73 74 75 76 77 78 79 |
# File 'lib/takagi/hooks.rb', line 72 def event_bus_ready? return false unless defined?(Takagi::EventBus) executor = Takagi::EventBus.instance_variable_get(:@executor) rescue nil return false if executor && executor.respond_to?(:running?) && !executor.running? true end |
.hook_address(event) ⇒ Object
68 69 70 |
# File 'lib/takagi/hooks.rb', line 68 def hook_address(event) "hooks.#{event}" end |
.subscribe(event, handler = nil) {|Hash| ... } ⇒ #call
Register a handler for a given event symbol.
19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/takagi/hooks.rb', line 19 def subscribe(event, handler = nil, &block) callback = handler || block raise ArgumentError, 'handler or block required' unless callback if event_bus_ready? Takagi::EventBus.consumer(hook_address(event), local_only: true) do || callback.call(.body) end else @mutex.synchronize { @subscribers[event] << callback } callback end end |
.unsubscribe(event, handler) ⇒ Object
Remove a previously registered handler.
37 38 39 40 41 42 43 |
# File 'lib/takagi/hooks.rb', line 37 def unsubscribe(event, handler) if event_bus_ready? Takagi::EventBus.unregister(handler) else @mutex.synchronize { @subscribers[event].delete(handler) } end end |