Class: Tavern::Subscriptions

Inherits:
Object
  • Object
show all
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:

  1. The root level - Currently, nothing subscribes to this level

  2. The “a” level - this is nested under the root level.

  3. The “b” level - this is nested under the “a” level.

  4. 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

Constructor Details

#initializeSubscriptions

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.

Parameters:

  • subscription (Subscription)

    the new subscription to add



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”.

Parameters:

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

    the given context for this publish call

Options Hash (context):

  • :path_parts (Array<String>)

    an array of the current children keys to dispatch on



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.

Parameters:

  • subscription (Subscription)

    the old subscription to remove



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.

Parameters:

  • key (String)

    the key of the given sublevel

Returns:



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.

Parameters:

  • parts (Array<String>)

    the list of path-parts to reach the desired sublevel.

Returns:



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