Class: Tavern::Subscriptions
- Inherits:
-
Object
- Object
- Tavern::Subscriptions
- Defined in:
- lib/tavern/subscriptions.rb
Overview
Tavern::Subscriptions implements a simple tree-like structure for handling subscriptions, facilitating the efficient depth-first processing of callbacks based on a given path.
Each level of the tree is composed of some callbacks as well as a set of sublevels, each represented by part of a subscription namespace. Namely, given a key of “a:b:c”, there will be four levels:
-
The root level - Currently, nothing subscribes to this level
-
The “a” level - this is nested under the root level.
-
The “b” level - this is nested under the “a” level.
-
The “c” level - this is nested under the “b” level.
When an event is published to “a:b:c”, the top level Subscriptions instance will recursively “#call“ the child levels, breaking if at any point a subscription returns false. Ideally, this means that for a normal event, we will get events (if present) invoked on all four levels, allowing a nice and structured event dispatch.
Instance Method Summary collapse
-
#add(subscription) ⇒ Object
Adds a new subscription to this subscriptions list.
-
#call(context = {}) ⇒ Object
Given a specified context, calls all nested matching subcontexts and then invokes the callbacks on this level, breaking if it encounters false (like terminators in AS callbacks).
-
#delete(subscription) ⇒ Object
Removes a given subscription from this level.
-
#initialize ⇒ Subscriptions
constructor
Creates a new subscription with an empty list of subscriptions and an empty subkeys mapping.
-
#sublevel(key) ⇒ Subscriptions
Gets the sublevel with the given key, initializing a new sublevel if it is as of yet unknown.
-
#sublevel_at(*parts) ⇒ Subscriptions
Given a list of subkeys, will return the association sublevel.
Constructor Details
#initialize ⇒ Subscriptions
Creates a new subscription with an empty list of subscriptions and an empty subkeys mapping.
20 21 22 23 |
# File 'lib/tavern/subscriptions.rb', line 20 def initialize @subscriptions = [] @subkeys = {} end |
Instance Method Details
#add(subscription) ⇒ Object
Adds a new subscription to this subscriptions list.
51 52 53 |
# File 'lib/tavern/subscriptions.rb', line 51 def add(subscription) @subscriptions << subscription end |
#call(context = {}) ⇒ Object
Given a specified context, calls all nested matching subcontexts and then invokes the callbacks on this level, breaking if it encounters false (like terminators in AS callbacks).
This means that if your subscription returns false, it will halt further callbacks. Also, It also means that dispatching events are depth first based on the key. E.g., given a callback key of “a:b:c”, the callbacks for “a:b:c” will be called first followed by those for “a:b” and “a”.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/tavern/subscriptions.rb', line 34 def call(context = {}) path_parts = context[:path_parts].dup # Call the sublevel, breaking when a value returns false if path_parts.any? and (subkey = @subkeys[path_parts.shift]) result = subkey.call context.merge(:path_parts => path_parts) return result if result == false end # Iterate over the subscriptions, breaking when one of them returns false @subscriptions.each do |subscription| return false if subscription.call(context) == false end # Otherwise, return nil true end |
#delete(subscription) ⇒ Object
Removes a given subscription from this level.
57 58 59 |
# File 'lib/tavern/subscriptions.rb', line 57 def delete(subscription) @subscriptions.delete subscription end |
#sublevel(key) ⇒ Subscriptions
Gets the sublevel with the given key, initializing a new sublevel if it is as of yet unknown.
65 66 67 |
# File 'lib/tavern/subscriptions.rb', line 65 def sublevel(key) @subkeys[key] ||= Subscriptions.new end |
#sublevel_at(*parts) ⇒ Subscriptions
Given a list of subkeys, will return the association sublevel.
72 73 74 75 76 |
# File 'lib/tavern/subscriptions.rb', line 72 def sublevel_at(*parts) parts.flatten.inject(self) do |level, part| level.sublevel part end end |