announcer 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/announcer.rb +32 -0
- data/lib/{ribbon/event_bus → announcer}/config.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/errors.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/event.rb +3 -3
- data/lib/announcer/instance.rb +158 -0
- data/lib/announcer/mixins.rb +7 -0
- data/lib/{ribbon/event_bus → announcer}/mixins/has_config.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/mixins/has_instance.rb +4 -4
- data/lib/{ribbon/event_bus → announcer}/mixins/serializable.rb +4 -4
- data/lib/announcer/plugins.rb +6 -0
- data/lib/{ribbon/event_bus → announcer}/plugins/logging_plugin.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/plugins/plugin.rb +4 -4
- data/lib/{ribbon/event_bus → announcer}/publishers.rb +7 -7
- data/lib/{ribbon/event_bus → announcer}/publishers/async_resque_publisher.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/publishers/proc_publisher.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/publishers/publisher.rb +1 -1
- data/lib/{ribbon/event_bus → announcer}/publishers/remote_resque_publisher.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/publishers/resque_publisher.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/publishers/subscriptions_publisher.rb +2 -2
- data/lib/{ribbon/event_bus → announcer}/subscription.rb +6 -6
- data/lib/announcer/version.rb +3 -0
- metadata +32 -32
- data/lib/ribbon/event_bus.rb +0 -37
- data/lib/ribbon/event_bus/instance.rb +0 -160
- data/lib/ribbon/event_bus/mixins.rb +0 -7
- data/lib/ribbon/event_bus/plugins.rb +0 -6
- data/lib/ribbon/event_bus/version.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 160662261dd1515502a39b4982427d83c117bdfa
|
4
|
+
data.tar.gz: b11ad4e2af0c3f63b8144955c29a0217e0ef591a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41ae357d6fb3fa45a62e8727ecce3f11605026298380cf1e4f79608fd2dcb277642e441aee7db9e8e130305be90e9755abea7bdf51c5e8602cccebb5a40ae092
|
7
|
+
data.tar.gz: b952e2c98ea8df540cfacbee0c2a79d3bbb6d4f5e5367850368a8763a93b17538339607b45a65b713a92f5a58090041eb1df38ef56f7be731e6c59e3362ee145
|
data/lib/announcer.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Announcer
|
2
|
+
autoload(:Instance, 'announcer/instance')
|
3
|
+
autoload(:Config, 'announcer/config')
|
4
|
+
autoload(:Publishers, 'announcer/publishers')
|
5
|
+
autoload(:Plugins, 'announcer/plugins')
|
6
|
+
autoload(:Event, 'announcer/event')
|
7
|
+
autoload(:Subscription, 'announcer/subscription')
|
8
|
+
autoload(:Mixins, 'announcer/mixins')
|
9
|
+
autoload(:Errors, 'announcer/errors')
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
def method_missing(meth, *args, &block)
|
14
|
+
instance.send(meth, *args, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def instance(name=:primary)
|
18
|
+
_registered_instances[name.to_sym] || Instance.new(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def _registered_instances
|
22
|
+
@__registered_instances ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def _register_instance(instance)
|
26
|
+
if _registered_instances.key?(instance.name)
|
27
|
+
raise Errors::DuplicateInstanceNameError, instance.name
|
28
|
+
else
|
29
|
+
_registered_instances[instance.name] = instance
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Announcer
|
4
4
|
class Config
|
5
5
|
# Putting this here instead of in Errors because I may move this into a
|
6
6
|
# separate gem.
|
@@ -129,4 +129,4 @@ module Ribbon::EventBus
|
|
129
129
|
@_nested ||= Hash.new { |hash, key| hash[key] = UndefinedValue.new }
|
130
130
|
end
|
131
131
|
end # Config
|
132
|
-
end #
|
132
|
+
end # Announcer
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Announcer
|
2
2
|
class Event
|
3
3
|
include Mixins::HasInstance
|
4
4
|
include Mixins::HasConfig
|
@@ -63,7 +63,7 @@ module Ribbon::EventBus
|
|
63
63
|
|
64
64
|
###
|
65
65
|
# Sanitize the event params.
|
66
|
-
# Prevents passing values that could cause errors later in
|
66
|
+
# Prevents passing values that could cause errors later in Announcer.
|
67
67
|
###
|
68
68
|
def _sanitize_params(params)
|
69
69
|
Hash[params.map { |key, value| [key.to_sym, _sanitize_value(key, value)] }].freeze
|
@@ -90,4 +90,4 @@ module Ribbon::EventBus
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end # Event
|
93
|
-
end #
|
93
|
+
end # Announcer
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'plugins'
|
2
|
+
|
3
|
+
module Announcer
|
4
|
+
DEFAULT_CONFIG_PATH = File.expand_path('../../../config/defaults.yml', __FILE__).freeze
|
5
|
+
|
6
|
+
##############################################################################
|
7
|
+
# Instance
|
8
|
+
#
|
9
|
+
# Represents an instance of the Announcer. Allows multiple Instances to be
|
10
|
+
# created with separate configuration, subscriptions, etc. Primarily intended
|
11
|
+
# to help testing, but there are practical use-cases as well.
|
12
|
+
##############################################################################
|
13
|
+
class Instance
|
14
|
+
include Mixins::Serializable
|
15
|
+
include ::Plugins::ComponentMixin
|
16
|
+
|
17
|
+
serialize_with :name
|
18
|
+
|
19
|
+
plugin_loader do |plugin|
|
20
|
+
_translate_object_to_plugin(plugin)
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :name
|
24
|
+
attr_reader :publishers
|
25
|
+
|
26
|
+
def initialize(name=nil)
|
27
|
+
if name
|
28
|
+
@name = name.to_sym
|
29
|
+
Announcer._register_instance(self) if @name
|
30
|
+
end
|
31
|
+
|
32
|
+
_load_default_config
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.load_from_serialized(name)
|
36
|
+
if name
|
37
|
+
Announcer.instance(name)
|
38
|
+
else
|
39
|
+
raise Errors::InstanceError, "Can't deserialize an unnamed Instance"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def config(&block)
|
44
|
+
(@__config ||= Config.new).tap { |config|
|
45
|
+
if block_given?
|
46
|
+
config.define(&block)
|
47
|
+
_process_config
|
48
|
+
end
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def plugin(*args)
|
53
|
+
config { plugin(*args) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def publish(*args)
|
57
|
+
raise Errors::NoPublishersDefinedError unless publishers && !publishers.empty?
|
58
|
+
_args_to_event(*args).publish
|
59
|
+
end
|
60
|
+
|
61
|
+
def subscribe_to(event_name, params={}, &block)
|
62
|
+
Subscription.new(event_name, params.merge(instance: self), &block)
|
63
|
+
end
|
64
|
+
|
65
|
+
def subscriptions_to(event_or_name)
|
66
|
+
event_name = event_or_name.is_a?(Event) ? event_or_name.name : event_or_name.to_sym
|
67
|
+
_registered_subscriptions_to(event_name).dup
|
68
|
+
end
|
69
|
+
|
70
|
+
def find_subscription(identifier)
|
71
|
+
_subscriptions_by_identifiers[identifier]
|
72
|
+
end
|
73
|
+
|
74
|
+
def find_publisher(publisher)
|
75
|
+
klass = Publishers.load(publisher)
|
76
|
+
publishers && publishers.find { |pub| pub.is_a?(klass) }
|
77
|
+
end
|
78
|
+
|
79
|
+
def has_publisher?(publisher)
|
80
|
+
!!find_publisher(publisher)
|
81
|
+
end
|
82
|
+
|
83
|
+
def _register_subscription(subscription)
|
84
|
+
if _subscriptions_by_identifiers[subscription.identifier]
|
85
|
+
# This is not expected to occur
|
86
|
+
raise Errors::SubscriptionError, "duplicate identifier: #{subscription.identifier.inspect}"
|
87
|
+
else
|
88
|
+
_subscriptions_by_identifiers[subscription.identifier] = subscription
|
89
|
+
end
|
90
|
+
|
91
|
+
_registered_subscriptions_to(subscription.event_name)
|
92
|
+
.push(subscription)
|
93
|
+
.sort! { |x, y| x.priority <=> y.priority }
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def _translate_object_to_plugin(object)
|
98
|
+
case object
|
99
|
+
when String, Symbol
|
100
|
+
_translate_string_to_plugin(object.to_s)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def _translate_string_to_plugin(string)
|
105
|
+
begin
|
106
|
+
Plugins.const_get(
|
107
|
+
string.split('_').map(&:capitalize).join + 'Plugin'
|
108
|
+
)
|
109
|
+
rescue
|
110
|
+
nil # Let the Plugins gem handle this.
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def _registered_subscriptions_to(event_name)
|
115
|
+
(@__registered_subscriptions ||= {})[event_name] ||= []
|
116
|
+
end
|
117
|
+
|
118
|
+
def _subscriptions_by_identifiers
|
119
|
+
@__registered_subscriptions_by_identifier ||= {}
|
120
|
+
end
|
121
|
+
|
122
|
+
def _load_default_config
|
123
|
+
config.merge_config_file!(DEFAULT_CONFIG_PATH)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Attempt to convert *args to an event object.
|
127
|
+
def _args_to_event(name_or_event, params={})
|
128
|
+
raise ArgumentError, 'event parameters must be a hash' unless params.is_a?(Hash)
|
129
|
+
|
130
|
+
case name_or_event
|
131
|
+
when Event
|
132
|
+
name_or_event.tap { |e| e.instance_variable_set(:@instance, self) }
|
133
|
+
else
|
134
|
+
Event.new(name_or_event, params.merge(instance: self))
|
135
|
+
end
|
136
|
+
end # _args_to_event
|
137
|
+
|
138
|
+
def _process_config
|
139
|
+
@publishers = _load_publishers.dup.freeze
|
140
|
+
_update_plugins
|
141
|
+
end
|
142
|
+
|
143
|
+
def _load_publishers
|
144
|
+
Publishers.load_for_instance(self)
|
145
|
+
end
|
146
|
+
|
147
|
+
def _update_plugins
|
148
|
+
plugins.clear
|
149
|
+
|
150
|
+
if config.plugin?
|
151
|
+
config.plugin.each { |plugin|
|
152
|
+
plugin = [plugin] unless plugin.is_a?(Array)
|
153
|
+
plugins.add(*plugin)
|
154
|
+
}
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end # Instance
|
158
|
+
end # Announcer
|
@@ -1,8 +1,8 @@
|
|
1
|
-
module
|
2
|
-
module
|
1
|
+
module Announcer
|
2
|
+
module Mixins
|
3
3
|
module HasInstance
|
4
4
|
def instance
|
5
|
-
(defined?(@instance) && @instance) ||
|
5
|
+
(defined?(@instance) && @instance) || Announcer.instance
|
6
6
|
end
|
7
7
|
|
8
8
|
def plugins
|
@@ -10,4 +10,4 @@ module Ribbon
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
|
-
end
|
13
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'base64'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Announcer
|
4
4
|
module Mixins
|
5
5
|
module Serializable
|
6
6
|
MAGIC = :SRLZ
|
@@ -79,11 +79,11 @@ module Ribbon::EventBus
|
|
79
79
|
###
|
80
80
|
|
81
81
|
def _serializable_encode_class(klass)
|
82
|
-
klass.name.to_s.sub('
|
82
|
+
klass.name.to_s.sub('Announcer::', '').to_sym
|
83
83
|
end
|
84
84
|
|
85
85
|
def _serializable_decode_class(encoded_klass)
|
86
|
-
|
86
|
+
Announcer.const_get(encoded_klass.to_s)
|
87
87
|
end
|
88
88
|
|
89
89
|
###
|
@@ -180,4 +180,4 @@ module Ribbon::EventBus
|
|
180
180
|
end
|
181
181
|
end
|
182
182
|
end
|
183
|
-
end
|
183
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require '
|
1
|
+
require 'plugins'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Announcer
|
4
4
|
module Plugins
|
5
|
-
class Plugin <
|
5
|
+
class Plugin < ::Plugins::Plugin
|
6
6
|
include Mixins::HasInstance
|
7
7
|
include Mixins::HasConfig
|
8
8
|
|
@@ -19,4 +19,4 @@ module Ribbon::EventBus
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
|
-
end
|
22
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
|
-
module
|
1
|
+
module Announcer
|
2
2
|
module Publishers
|
3
3
|
autoload(:Publisher,
|
4
|
-
'
|
4
|
+
'announcer/publishers/publisher')
|
5
5
|
autoload(:ProcPublisher,
|
6
|
-
'
|
6
|
+
'announcer/publishers/proc_publisher')
|
7
7
|
autoload(:SubscriptionsPublisher,
|
8
|
-
'
|
8
|
+
'announcer/publishers/subscriptions_publisher')
|
9
9
|
autoload(:ResquePublisher,
|
10
|
-
'
|
10
|
+
'announcer/publishers/resque_publisher')
|
11
11
|
autoload(:RemoteResquePublisher,
|
12
|
-
'
|
12
|
+
'announcer/publishers/remote_resque_publisher')
|
13
13
|
autoload(:AsyncResquePublisher,
|
14
|
-
'
|
14
|
+
'announcer/publishers/async_resque_publisher')
|
15
15
|
|
16
16
|
module_function
|
17
17
|
def load_for_instance(instance)
|
@@ -2,7 +2,7 @@ require 'resque'
|
|
2
2
|
require 'redis'
|
3
3
|
require 'celluloid/current'
|
4
4
|
|
5
|
-
module
|
5
|
+
module Announcer
|
6
6
|
module Publishers
|
7
7
|
class AsyncResquePublisher < Publisher
|
8
8
|
config_key :resque
|
@@ -15,7 +15,7 @@ module Ribbon::EventBus
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def worker_id
|
18
|
-
@__worker_id ||= "
|
18
|
+
@__worker_id ||= "announcer_resque_worker_#{object_id}".to_sym
|
19
19
|
end
|
20
20
|
|
21
21
|
##
|
@@ -2,7 +2,7 @@ require 'uri'
|
|
2
2
|
require 'redis'
|
3
3
|
require 'redis/namespace'
|
4
4
|
|
5
|
-
module
|
5
|
+
module Announcer
|
6
6
|
module Publishers
|
7
7
|
class RemoteResquePublisher < Publisher
|
8
8
|
config_key :remote_resque
|
@@ -78,4 +78,4 @@ module Ribbon::EventBus
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
-
end
|
81
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'resque'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Announcer
|
4
4
|
module Publishers
|
5
5
|
class ResquePublisher < Publisher
|
6
6
|
config_key :resque
|
@@ -79,7 +79,7 @@ module Ribbon::EventBus
|
|
79
79
|
def _disallow_multiple_per_instance
|
80
80
|
if instance.has_publisher?(:resque)
|
81
81
|
raise Errors::PublisherError,
|
82
|
-
"cannot have multiple ResquePublishers in an
|
82
|
+
"cannot have multiple ResquePublishers in an Announcer instance"
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'digest'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Announcer
|
4
4
|
class Subscription
|
5
5
|
include Mixins::HasInstance
|
6
6
|
include Mixins::HasConfig
|
@@ -61,14 +61,14 @@ module Ribbon::EventBus
|
|
61
61
|
|
62
62
|
# Will be something like:
|
63
63
|
# "/path/to/file.rb:47:in `method_name'"
|
64
|
-
|
64
|
+
non_announcer_caller = caller.find { |c| !c.start_with?(path) }
|
65
65
|
|
66
|
-
unless
|
66
|
+
unless non_announcer_caller
|
67
67
|
# This is not expected to occur.
|
68
|
-
raise Errors::SubscriptionError, "Could not find non-
|
68
|
+
raise Errors::SubscriptionError, "Could not find non-Announcer caller"
|
69
69
|
end
|
70
70
|
|
71
|
-
|
71
|
+
non_announcer_caller
|
72
72
|
end
|
73
73
|
|
74
74
|
##
|
@@ -162,4 +162,4 @@ module Ribbon::EventBus
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
end # Event
|
165
|
-
end #
|
165
|
+
end # Announcer
|
metadata
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: announcer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Honer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: plugins
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.3.0
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.3.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 0.3.0
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
32
|
+
version: 0.3.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: celluloid
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,36 +156,36 @@ dependencies:
|
|
156
156
|
- - ">="
|
157
157
|
- !ruby/object:Gem::Version
|
158
158
|
version: '0'
|
159
|
-
description:
|
159
|
+
description: A flexible event bus for Ruby.
|
160
160
|
email:
|
161
|
-
- robert@
|
161
|
+
- robert@payout.com
|
162
162
|
executables: []
|
163
163
|
extensions: []
|
164
164
|
extra_rdoc_files: []
|
165
165
|
files:
|
166
166
|
- config/defaults.yml
|
167
|
-
- lib/
|
168
|
-
- lib/
|
169
|
-
- lib/
|
170
|
-
- lib/
|
171
|
-
- lib/
|
172
|
-
- lib/
|
173
|
-
- lib/
|
174
|
-
- lib/
|
175
|
-
- lib/
|
176
|
-
- lib/
|
177
|
-
- lib/
|
178
|
-
- lib/
|
179
|
-
- lib/
|
180
|
-
- lib/
|
181
|
-
- lib/
|
182
|
-
- lib/
|
183
|
-
- lib/
|
184
|
-
- lib/
|
185
|
-
- lib/
|
186
|
-
- lib/
|
187
|
-
- lib/
|
188
|
-
homepage: http://github.com/
|
167
|
+
- lib/announcer.rb
|
168
|
+
- lib/announcer/config.rb
|
169
|
+
- lib/announcer/errors.rb
|
170
|
+
- lib/announcer/event.rb
|
171
|
+
- lib/announcer/instance.rb
|
172
|
+
- lib/announcer/mixins.rb
|
173
|
+
- lib/announcer/mixins/has_config.rb
|
174
|
+
- lib/announcer/mixins/has_instance.rb
|
175
|
+
- lib/announcer/mixins/serializable.rb
|
176
|
+
- lib/announcer/plugins.rb
|
177
|
+
- lib/announcer/plugins/logging_plugin.rb
|
178
|
+
- lib/announcer/plugins/plugin.rb
|
179
|
+
- lib/announcer/publishers.rb
|
180
|
+
- lib/announcer/publishers/async_resque_publisher.rb
|
181
|
+
- lib/announcer/publishers/proc_publisher.rb
|
182
|
+
- lib/announcer/publishers/publisher.rb
|
183
|
+
- lib/announcer/publishers/remote_resque_publisher.rb
|
184
|
+
- lib/announcer/publishers/resque_publisher.rb
|
185
|
+
- lib/announcer/publishers/subscriptions_publisher.rb
|
186
|
+
- lib/announcer/subscription.rb
|
187
|
+
- lib/announcer/version.rb
|
188
|
+
homepage: http://github.com/payout/announcer
|
189
189
|
licenses:
|
190
190
|
- BSD
|
191
191
|
metadata: {}
|
@@ -208,5 +208,5 @@ rubyforge_project:
|
|
208
208
|
rubygems_version: 2.4.3
|
209
209
|
signing_key:
|
210
210
|
specification_version: 4
|
211
|
-
summary:
|
211
|
+
summary: A flexible event bus for Ruby.
|
212
212
|
test_files: []
|
data/lib/ribbon/event_bus.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
module Ribbon
|
2
|
-
module EventBus
|
3
|
-
autoload(:Instance, 'ribbon/event_bus/instance')
|
4
|
-
autoload(:Config, 'ribbon/event_bus/config')
|
5
|
-
autoload(:Publishers, 'ribbon/event_bus/publishers')
|
6
|
-
autoload(:Plugins, 'ribbon/event_bus/plugins')
|
7
|
-
autoload(:Event, 'ribbon/event_bus/event')
|
8
|
-
autoload(:Subscription, 'ribbon/event_bus/subscription')
|
9
|
-
autoload(:Mixins, 'ribbon/event_bus/mixins')
|
10
|
-
autoload(:Errors, 'ribbon/event_bus/errors')
|
11
|
-
|
12
|
-
module_function
|
13
|
-
|
14
|
-
def method_missing(meth, *args, &block)
|
15
|
-
instance.send(meth, *args, &block)
|
16
|
-
end
|
17
|
-
|
18
|
-
def instance(name=:primary)
|
19
|
-
_registered_instances[name.to_sym] || Instance.new(name)
|
20
|
-
end
|
21
|
-
|
22
|
-
def _registered_instances
|
23
|
-
@__registered_instances ||= {}
|
24
|
-
end
|
25
|
-
|
26
|
-
def _register_instance(instance)
|
27
|
-
if _registered_instances.key?(instance.name)
|
28
|
-
raise Errors::DuplicateInstanceNameError, instance.name
|
29
|
-
else
|
30
|
-
_registered_instances[instance.name] = instance
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Create a shortcut
|
37
|
-
EventBus = Ribbon::EventBus
|
@@ -1,160 +0,0 @@
|
|
1
|
-
require 'ribbon/plugins'
|
2
|
-
|
3
|
-
module Ribbon
|
4
|
-
module EventBus
|
5
|
-
DEFAULT_CONFIG_PATH = File.expand_path('../../../../config/defaults.yml', __FILE__).freeze
|
6
|
-
|
7
|
-
##############################################################################
|
8
|
-
# Instance
|
9
|
-
#
|
10
|
-
# Represents an instance of the EventBus. Allows multiple Instances to be
|
11
|
-
# created with separate configuration, subscriptions, etc. Primarily intended
|
12
|
-
# to help testing, but there are practical use-cases as well.
|
13
|
-
##############################################################################
|
14
|
-
class Instance
|
15
|
-
include Mixins::Serializable
|
16
|
-
include Ribbon::Plugins::ComponentMixin
|
17
|
-
|
18
|
-
serialize_with :name
|
19
|
-
|
20
|
-
plugin_loader do |plugin|
|
21
|
-
_translate_object_to_plugin(plugin)
|
22
|
-
end
|
23
|
-
|
24
|
-
attr_reader :name
|
25
|
-
attr_reader :publishers
|
26
|
-
|
27
|
-
def initialize(name=nil)
|
28
|
-
if name
|
29
|
-
@name = name.to_sym
|
30
|
-
EventBus._register_instance(self) if @name
|
31
|
-
end
|
32
|
-
|
33
|
-
_load_default_config
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.load_from_serialized(name)
|
37
|
-
if name
|
38
|
-
EventBus.instance(name)
|
39
|
-
else
|
40
|
-
raise Errors::InstanceError, "Can't deserialize an unnamed Instance"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def config(&block)
|
45
|
-
(@__config ||= Config.new).tap { |config|
|
46
|
-
if block_given?
|
47
|
-
config.define(&block)
|
48
|
-
_process_config
|
49
|
-
end
|
50
|
-
}
|
51
|
-
end
|
52
|
-
|
53
|
-
def plugin(*args)
|
54
|
-
config { plugin(*args) }
|
55
|
-
end
|
56
|
-
|
57
|
-
def publish(*args)
|
58
|
-
raise Errors::NoPublishersDefinedError unless publishers && !publishers.empty?
|
59
|
-
_args_to_event(*args).publish
|
60
|
-
end
|
61
|
-
|
62
|
-
def subscribe_to(event_name, params={}, &block)
|
63
|
-
Subscription.new(event_name, params.merge(instance: self), &block)
|
64
|
-
end
|
65
|
-
|
66
|
-
def subscriptions_to(event_or_name)
|
67
|
-
event_name = event_or_name.is_a?(Event) ? event_or_name.name : event_or_name.to_sym
|
68
|
-
_registered_subscriptions_to(event_name).dup
|
69
|
-
end
|
70
|
-
|
71
|
-
def find_subscription(identifier)
|
72
|
-
_subscriptions_by_identifiers[identifier]
|
73
|
-
end
|
74
|
-
|
75
|
-
def find_publisher(publisher)
|
76
|
-
klass = Publishers.load(publisher)
|
77
|
-
publishers && publishers.find { |pub| pub.is_a?(klass) }
|
78
|
-
end
|
79
|
-
|
80
|
-
def has_publisher?(publisher)
|
81
|
-
!!find_publisher(publisher)
|
82
|
-
end
|
83
|
-
|
84
|
-
def _register_subscription(subscription)
|
85
|
-
if _subscriptions_by_identifiers[subscription.identifier]
|
86
|
-
# This is not expected to occur
|
87
|
-
raise Errors::SubscriptionError, "duplicate identifier: #{subscription.identifier.inspect}"
|
88
|
-
else
|
89
|
-
_subscriptions_by_identifiers[subscription.identifier] = subscription
|
90
|
-
end
|
91
|
-
|
92
|
-
_registered_subscriptions_to(subscription.event_name)
|
93
|
-
.push(subscription)
|
94
|
-
.sort! { |x, y| x.priority <=> y.priority }
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
def _translate_object_to_plugin(object)
|
99
|
-
case object
|
100
|
-
when String, Symbol
|
101
|
-
_translate_string_to_plugin(object.to_s)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def _translate_string_to_plugin(string)
|
106
|
-
begin
|
107
|
-
Plugins.const_get(
|
108
|
-
string.split('_').map(&:capitalize).join + 'Plugin'
|
109
|
-
)
|
110
|
-
rescue
|
111
|
-
nil # Let the Plugins gem handle this.
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def _registered_subscriptions_to(event_name)
|
116
|
-
(@__registered_subscriptions ||= {})[event_name] ||= []
|
117
|
-
end
|
118
|
-
|
119
|
-
def _subscriptions_by_identifiers
|
120
|
-
@__registered_subscriptions_by_identifier ||= {}
|
121
|
-
end
|
122
|
-
|
123
|
-
def _load_default_config
|
124
|
-
config.merge_config_file!(DEFAULT_CONFIG_PATH)
|
125
|
-
end
|
126
|
-
|
127
|
-
# Attempt to convert *args to an event object.
|
128
|
-
def _args_to_event(name_or_event, params={})
|
129
|
-
raise ArgumentError, 'event parameters must be a hash' unless params.is_a?(Hash)
|
130
|
-
|
131
|
-
case name_or_event
|
132
|
-
when Event
|
133
|
-
name_or_event.tap { |e| e.instance_variable_set(:@instance, self) }
|
134
|
-
else
|
135
|
-
Event.new(name_or_event, params.merge(instance: self))
|
136
|
-
end
|
137
|
-
end # _args_to_event
|
138
|
-
|
139
|
-
def _process_config
|
140
|
-
@publishers = _load_publishers.dup.freeze
|
141
|
-
_update_plugins
|
142
|
-
end
|
143
|
-
|
144
|
-
def _load_publishers
|
145
|
-
Publishers.load_for_instance(self)
|
146
|
-
end
|
147
|
-
|
148
|
-
def _update_plugins
|
149
|
-
plugins.clear
|
150
|
-
|
151
|
-
if config.plugin?
|
152
|
-
config.plugin.each { |plugin|
|
153
|
-
plugin = [plugin] unless plugin.is_a?(Array)
|
154
|
-
plugins.add(*plugin)
|
155
|
-
}
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end # Instance
|
159
|
-
end # EventBus
|
160
|
-
end # Ribbon
|