Class: PubSubHub
- Inherits:
-
Object
- Object
- PubSubHub
- Extended by:
- Forwardable
- Includes:
- Singleton
- Defined in:
- lib/pubsubhub.rb
Overview
The ‘PubSubHub` provides a mechanism to subscribe to events and notify objects of events.
To subscribe to an event, add a hash to pub_sub_hub. The listener must implement ‘handle_#event_name`.
# {file:config/initializers/pub_sub_hub.rb}
PubSubHub.register(
took_action: [
{ listener: Mailer, async: true },
],
)
To trigger an event, call ‘PubSubHub.trigger`. All the arguments are forwarded to the `listener`.
class Action
def take_action(person)
# ...
PubSubHub.trigger :took_action, self, person
end
end
class Mailer
def self.handle_took_action(action, person)
# send `action.creator` an email
end
end
By default, exceptions raised during event propagation are handled by printing them to standard error. You can set a custom handler by passing in a callable object to ‘PubSubHub.error_handler=`. We use this at Causes to integrate with our `Oops` plug-in, without creating a hard dependency on it:
PubSubHub.error_handler = ->(exception) { Oops.log(exception) }
Likewise, dispatch of ‘async: true` events is handled by a callable passed in to `PubSubHub.async_dispatcher=`. The default implementation just calls `Object#send` (ie. it is not actually asynchronous). At Causes, we’ve supplied a custom dispatcher that relies on the async_observer plug-in:
PubSubHub.async_dispatcher = ->(listener, handler, args) do
listener.async_send(handler, *args)
end
Constant Summary collapse
- VERSION =
'0.0.5'
Instance Attribute Summary collapse
-
#async_dispatcher ⇒ Object
Returns the value of attribute async_dispatcher.
-
#error_handler ⇒ Object
Returns the value of attribute error_handler.
-
#registry ⇒ Object
readonly
Returns the value of attribute registry.
Instance Method Summary collapse
-
#initialize ⇒ PubSubHub
constructor
A new instance of PubSubHub.
- #register(registry) ⇒ Object
-
#trigger(event_name, *args) ⇒ Object
Notifies listeners of a event.
Constructor Details
#initialize ⇒ PubSubHub
Returns a new instance of PubSubHub.
72 73 74 75 76 77 78 |
# File 'lib/pubsubhub.rb', line 72 def initialize @async_dispatcher = ->(listener, handler, args) do listener.send(handler, *args) end @error_handler = ->(exception) { STDERR.puts exception } end |
Instance Attribute Details
#async_dispatcher ⇒ Object
Returns the value of attribute async_dispatcher.
69 70 71 |
# File 'lib/pubsubhub.rb', line 69 def async_dispatcher @async_dispatcher end |
#error_handler ⇒ Object
Returns the value of attribute error_handler.
69 70 71 |
# File 'lib/pubsubhub.rb', line 69 def error_handler @error_handler end |
#registry ⇒ Object (readonly)
Returns the value of attribute registry.
70 71 72 |
# File 'lib/pubsubhub.rb', line 70 def registry @registry end |
Instance Method Details
#register(registry) ⇒ Object
80 81 82 |
# File 'lib/pubsubhub.rb', line 80 def register(registry) @registry = validate_registry!(registry) end |
#trigger(event_name, *args) ⇒ Object
Notifies listeners of a event.
Arguments are forwarded to the handlers. If the listener registered with ‘async: true`, `trigger` calls the handler using an asynchronous dispatcher.
The default dispatcher just forwards the message directly. For an example of a dispatcher that is actually asynchronous, see pub_sub_hub, which sets up:
PubSubHub.async_dispatcher = ->(listener, handler, args) do
listener.async_send(handler, *args)
end
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/pubsubhub.rb', line 97 def trigger(event_name, *args) @registry.fetch(event_name.to_sym, []).each do |registration| begin listener = constantize(registration[:listener]) async = registration[:async] handler = :"handle_#{event_name}" if async @async_dispatcher.call(listener, handler, args) else listener.send(handler, *args) end rescue => e @error_handler.call(e) end end end |