announcer 0.5.1
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 +7 -0
- data/config/defaults.yml +13 -0
- data/lib/ribbon/event_bus.rb +37 -0
- data/lib/ribbon/event_bus/config.rb +132 -0
- data/lib/ribbon/event_bus/errors.rb +55 -0
- data/lib/ribbon/event_bus/event.rb +93 -0
- data/lib/ribbon/event_bus/instance.rb +160 -0
- data/lib/ribbon/event_bus/mixins.rb +7 -0
- data/lib/ribbon/event_bus/mixins/has_config.rb +45 -0
- data/lib/ribbon/event_bus/mixins/has_instance.rb +13 -0
- data/lib/ribbon/event_bus/mixins/serializable.rb +183 -0
- data/lib/ribbon/event_bus/plugins.rb +6 -0
- data/lib/ribbon/event_bus/plugins/logging_plugin.rb +68 -0
- data/lib/ribbon/event_bus/plugins/plugin.rb +22 -0
- data/lib/ribbon/event_bus/publishers.rb +54 -0
- data/lib/ribbon/event_bus/publishers/async_resque_publisher.rb +81 -0
- data/lib/ribbon/event_bus/publishers/proc_publisher.rb +22 -0
- data/lib/ribbon/event_bus/publishers/publisher.rb +30 -0
- data/lib/ribbon/event_bus/publishers/remote_resque_publisher.rb +81 -0
- data/lib/ribbon/event_bus/publishers/resque_publisher.rb +87 -0
- data/lib/ribbon/event_bus/publishers/subscriptions_publisher.rb +8 -0
- data/lib/ribbon/event_bus/subscription.rb +165 -0
- data/lib/ribbon/event_bus/version.rb +5 -0
- metadata +212 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ribbon::EventBus
|
2
|
+
module Publishers
|
3
|
+
class ProcPublisher < Publisher
|
4
|
+
def initialize(instance=nil, &block)
|
5
|
+
super
|
6
|
+
|
7
|
+
raise Errors::MissingProcError unless block_given?
|
8
|
+
raise Errors::InvalidArityError, 'Proc arity must be 1' unless block.arity == 1
|
9
|
+
@_block = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def new(instance=nil)
|
13
|
+
self.class.new(instance, &@_block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def publish(event)
|
17
|
+
super
|
18
|
+
@_block.call(event)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Ribbon::EventBus
|
2
|
+
module Publishers
|
3
|
+
class Publisher
|
4
|
+
include Mixins::HasInstance
|
5
|
+
include Mixins::HasConfig
|
6
|
+
config_key :publishers
|
7
|
+
|
8
|
+
def initialize(instance=nil, params={})
|
9
|
+
@instance = instance
|
10
|
+
@_params = params
|
11
|
+
end
|
12
|
+
|
13
|
+
def config
|
14
|
+
@__config ||= super.merge_hash!(@_params)
|
15
|
+
end
|
16
|
+
|
17
|
+
###
|
18
|
+
# #publish(event)
|
19
|
+
#
|
20
|
+
# This method should be overridden by a subclass. Make sure to call "super"
|
21
|
+
# so that proper sanity checks can be performed.
|
22
|
+
###
|
23
|
+
def publish(event)
|
24
|
+
unless event.instance == instance
|
25
|
+
raise Errors::PublisherError, "Event for different instance"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'redis'
|
3
|
+
require 'redis/namespace'
|
4
|
+
|
5
|
+
module Ribbon::EventBus
|
6
|
+
module Publishers
|
7
|
+
class RemoteResquePublisher < Publisher
|
8
|
+
config_key :remote_resque
|
9
|
+
|
10
|
+
def publish(event)
|
11
|
+
super
|
12
|
+
|
13
|
+
# Based on Resque 1.25.2
|
14
|
+
|
15
|
+
# Resque call stack:
|
16
|
+
# -> Resque.enqueue(klass, *args)
|
17
|
+
# -> Resque.enqueue_to(queue, klass, *args)
|
18
|
+
# -> Job.create(queue, klass, *args)
|
19
|
+
# -> Resque.push(queue, class: klass.to_s, args: args)
|
20
|
+
|
21
|
+
# These should be the same as the args passed to Resque.enqueue in
|
22
|
+
# ResquePublisher#publish(event).
|
23
|
+
args = [
|
24
|
+
event.serialize
|
25
|
+
]
|
26
|
+
|
27
|
+
enqueue_to(config.queue.to_s, Publishers::ResquePublisher::PublisherJob, *args)
|
28
|
+
end
|
29
|
+
|
30
|
+
def redis
|
31
|
+
@redis ||= _redis
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
##########################################################################
|
37
|
+
# Methods copied from Resque v1.25.2
|
38
|
+
##########################################################################
|
39
|
+
|
40
|
+
def enqueue_to(queue, klass, *args)
|
41
|
+
# This is a functionality copy, not a direct code copy.
|
42
|
+
# Here, I'm skipping the call to Job.create(queue, klass, *args) and
|
43
|
+
# calling push directly.
|
44
|
+
push(queue, class: klass.to_s, args: args)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Resque::push(queue, items)
|
48
|
+
def push(queue, item)
|
49
|
+
redis.pipelined do
|
50
|
+
watch_queue(queue)
|
51
|
+
redis.rpush "queue:#{queue}", encode(item)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Resque::watch_queue
|
56
|
+
def watch_queue(queue)
|
57
|
+
redis.sadd(:queues, queue.to_s)
|
58
|
+
end
|
59
|
+
|
60
|
+
def encode(object)
|
61
|
+
# This one we can call directly.
|
62
|
+
Resque.encode(object)
|
63
|
+
end
|
64
|
+
|
65
|
+
##########################################################################
|
66
|
+
# Helper Methods
|
67
|
+
##########################################################################
|
68
|
+
|
69
|
+
def _redis
|
70
|
+
if config.redis?
|
71
|
+
config.redis
|
72
|
+
elsif config.redis_url?
|
73
|
+
redis = Redis.connect(url: config.redis_url, thread_safe: true)
|
74
|
+
Redis::Namespace.new(config.redis_namespace.to_sym, redis: redis)
|
75
|
+
else
|
76
|
+
raise Errors::RemoteResquePublisherError, "missing redis configuration"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'resque'
|
2
|
+
|
3
|
+
module Ribbon::EventBus
|
4
|
+
module Publishers
|
5
|
+
class ResquePublisher < Publisher
|
6
|
+
config_key :resque
|
7
|
+
|
8
|
+
def initialize(instance=nil, params={})
|
9
|
+
super
|
10
|
+
_disallow_multiple_per_instance
|
11
|
+
end
|
12
|
+
|
13
|
+
def publish(event)
|
14
|
+
super
|
15
|
+
|
16
|
+
unless event.subscriptions.empty?
|
17
|
+
PublisherJob.set_queue(config.publisher_queue.to_sym)
|
18
|
+
Resque.enqueue(PublisherJob, event.serialize)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def subscription_queue_formatter
|
23
|
+
self.class.subscription_queue_formatter(config)
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def subscription_queue_formatter(config)
|
28
|
+
if config.subscription_queue_formatter?
|
29
|
+
formatter = config.subscription_queue_formatter
|
30
|
+
case formatter
|
31
|
+
when Array
|
32
|
+
formatter.last
|
33
|
+
when Proc
|
34
|
+
formatter
|
35
|
+
else
|
36
|
+
raise Errors::PublisherError, "Invalid subscription_queue_formatter: #{formatter.inspect}"
|
37
|
+
end
|
38
|
+
else
|
39
|
+
lambda { |subscription| "subscriptions_p#{subscription.priority}" }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end # Class Methods
|
43
|
+
|
44
|
+
module PublisherJob
|
45
|
+
def self.set_queue(queue)
|
46
|
+
@queue = queue
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.perform(serialized_event, publisher_name=:resque)
|
50
|
+
event = Event.deserialize(serialized_event)
|
51
|
+
instance = event.instance
|
52
|
+
|
53
|
+
publisher = instance.find_publisher(publisher_name)
|
54
|
+
raise Errors::PublisherError, 'No ResquePublisher found' unless publisher
|
55
|
+
queue_formatter = publisher.subscription_queue_formatter
|
56
|
+
|
57
|
+
instance.plugins.perform(:resque_publish, event) do |event|
|
58
|
+
event.subscriptions.each { |s|
|
59
|
+
SubscriptionJob.set_queue(queue_formatter.call(s).to_sym)
|
60
|
+
Resque.enqueue(SubscriptionJob, s.serialize, event.serialize)
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end # PublisherJob
|
65
|
+
|
66
|
+
module SubscriptionJob
|
67
|
+
def self.set_queue(queue)
|
68
|
+
@queue = queue
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.perform(serialized_sub, serialized_event)
|
72
|
+
subscription = Subscription.deserialize(serialized_sub)
|
73
|
+
event = Event.deserialize(serialized_event)
|
74
|
+
subscription.handle(event)
|
75
|
+
end
|
76
|
+
end # SubscriptionJob
|
77
|
+
|
78
|
+
private
|
79
|
+
def _disallow_multiple_per_instance
|
80
|
+
if instance.has_publisher?(:resque)
|
81
|
+
raise Errors::PublisherError,
|
82
|
+
"cannot have multiple ResquePublishers in an EventBus instance"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module Ribbon::EventBus
|
4
|
+
class Subscription
|
5
|
+
include Mixins::HasInstance
|
6
|
+
include Mixins::HasConfig
|
7
|
+
include Mixins::Serializable
|
8
|
+
|
9
|
+
config_key :subscriptions
|
10
|
+
serialize_with :instance, :identifier
|
11
|
+
|
12
|
+
attr_reader :name
|
13
|
+
attr_reader :event_name
|
14
|
+
attr_reader :priority
|
15
|
+
attr_reader :identifier
|
16
|
+
|
17
|
+
def initialize(event_name, params={}, &block)
|
18
|
+
@event_name = event_name.to_sym
|
19
|
+
@_block = block
|
20
|
+
|
21
|
+
_evaluate_params(params)
|
22
|
+
|
23
|
+
@identifier = _generate_identifier
|
24
|
+
|
25
|
+
if instance.find_subscription(identifier)
|
26
|
+
raise Errors::DuplicateIdentifierError, "give this subscription a unique name"
|
27
|
+
else
|
28
|
+
instance._register_subscription(self)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.load_from_serialized(instance, identifier)
|
33
|
+
instance.find_subscription(identifier)
|
34
|
+
end
|
35
|
+
|
36
|
+
def handle(event)
|
37
|
+
raise Errors::UnexpectedEventError, 'wrong name' unless event.name == event_name
|
38
|
+
raise Errors::UnexpectedEventError, 'wrong instance' unless event.instance == instance
|
39
|
+
|
40
|
+
plugins.perform(:subscription, self, event) { |subscription, event|
|
41
|
+
@_block.call(event)
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
"Subscription(on #{event_name}: #{name || _path})"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def _path
|
52
|
+
@__path ||= _determine_path
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Determines the file path of the ruby code defining the subscription.
|
57
|
+
# It's important that this is called from within the initializer to get the
|
58
|
+
# desired effect.
|
59
|
+
def _determine_path
|
60
|
+
path = File.expand_path('../..', __FILE__)
|
61
|
+
|
62
|
+
# Will be something like:
|
63
|
+
# "/path/to/file.rb:47:in `method_name'"
|
64
|
+
non_event_bus_caller = caller.find { |c| !c.start_with?(path) }
|
65
|
+
|
66
|
+
unless non_event_bus_caller
|
67
|
+
# This is not expected to occur.
|
68
|
+
raise Errors::SubscriptionError, "Could not find non-EventBus caller"
|
69
|
+
end
|
70
|
+
|
71
|
+
non_event_bus_caller
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Generates a unique identifier for this subscription which will be used to
|
76
|
+
# "serialize" it.
|
77
|
+
#
|
78
|
+
# The goal here is to generate a identifier that is the same across different
|
79
|
+
# processes and servers and that ideally changes infrequently between
|
80
|
+
# application versions, but when it does change, it should do so predictably.
|
81
|
+
def _generate_identifier
|
82
|
+
# Cut off everything from the line number onward. That way, the identifier
|
83
|
+
# does not change when the subscription block moves to a different line.
|
84
|
+
index = _path.rindex(/:\d+:/) - 1
|
85
|
+
path = _path[0..index]
|
86
|
+
|
87
|
+
raise Errors::SubscriptionError, "Invalid path: #{path}" unless File.exists?(path)
|
88
|
+
|
89
|
+
Digest::MD5.hexdigest("#{path}:#{event_name}:#{name}").to_sym
|
90
|
+
end
|
91
|
+
|
92
|
+
def _symbol_to_priority(sym)
|
93
|
+
(@__symbol_to_priority_map ||= _generate_priority_shortcut_map)[sym]
|
94
|
+
end
|
95
|
+
|
96
|
+
def _generate_priority_shortcut_map(max_priority=config.max_priority)
|
97
|
+
{}.tap { |map|
|
98
|
+
map.merge!(highest: 1, lowest: max_priority)
|
99
|
+
map[:medium] = (map[:lowest] / 2.0).ceil
|
100
|
+
map[:high] = (map[:medium] / 2.0).ceil
|
101
|
+
map[:low] = ((map[:lowest] + map[:medium]) / 2.0).ceil
|
102
|
+
}.freeze
|
103
|
+
end
|
104
|
+
|
105
|
+
############################################################################
|
106
|
+
# Parameter Evaluation Logic
|
107
|
+
#
|
108
|
+
# This evaluates the parameters passed to the initializer.
|
109
|
+
############################################################################
|
110
|
+
|
111
|
+
###
|
112
|
+
# Root evaluation method.
|
113
|
+
###
|
114
|
+
def _evaluate_params(params)
|
115
|
+
@instance = params[:instance]
|
116
|
+
@name = params[:name].to_s
|
117
|
+
@priority = _evaluate_priority(params[:priority])
|
118
|
+
end
|
119
|
+
|
120
|
+
###
|
121
|
+
# Priority evaluation
|
122
|
+
###
|
123
|
+
def _evaluate_priority(priority)
|
124
|
+
case priority
|
125
|
+
when Integer
|
126
|
+
_evaluate_priority_int(priority)
|
127
|
+
when String, Symbol
|
128
|
+
_evaluate_priority_symbol(priority.to_sym)
|
129
|
+
when NilClass
|
130
|
+
_evaluate_priority_nil
|
131
|
+
else
|
132
|
+
raise Errors::InvalidPriorityError, priority.inspect
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Evaluate an integer as a priority.
|
137
|
+
def _evaluate_priority_int(int)
|
138
|
+
raise Errors::InvalidPriorityError, int unless int > 0 && int <= config.max_priority
|
139
|
+
int
|
140
|
+
end
|
141
|
+
|
142
|
+
# Evaluate a symbol as a priority.
|
143
|
+
def _evaluate_priority_symbol(sym)
|
144
|
+
if (priority = _symbol_to_priority(sym))
|
145
|
+
_evaluate_priority(priority)
|
146
|
+
else
|
147
|
+
raise Errors::InvalidPriorityError, sym.inspect
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Evaluate nil as a priority.
|
152
|
+
def _evaluate_priority_nil
|
153
|
+
# Need to specify value explicitly here, otherwise in the call to
|
154
|
+
# _evaluate_priority, the case statement won't recognize it as a Symbol.
|
155
|
+
# That's because when calls Symbol::=== to evaluate a match.
|
156
|
+
priority = config.default_priority
|
157
|
+
|
158
|
+
if priority
|
159
|
+
_evaluate_priority(priority)
|
160
|
+
else
|
161
|
+
raise Errors::InvalidPriorityError, priority.inspect
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end # Event
|
165
|
+
end # Ribbon::EventBus
|
metadata
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: announcer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert Honer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ribbon-plugins
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.2'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.2.4
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.2'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.2.4
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: celluloid
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.17.2
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.17.2
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rails
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 4.0.13
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 4.0.13
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: sqlite3
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: redis
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: redis-namespace
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: resque
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.25.2
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 1.25.2
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: mock_redis
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: rspec
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: rspec-rails
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
description: An asynchronous event bus for Ruby.
|
160
|
+
email:
|
161
|
+
- robert@ribbonpayments.com
|
162
|
+
executables: []
|
163
|
+
extensions: []
|
164
|
+
extra_rdoc_files: []
|
165
|
+
files:
|
166
|
+
- config/defaults.yml
|
167
|
+
- lib/ribbon/event_bus.rb
|
168
|
+
- lib/ribbon/event_bus/config.rb
|
169
|
+
- lib/ribbon/event_bus/errors.rb
|
170
|
+
- lib/ribbon/event_bus/event.rb
|
171
|
+
- lib/ribbon/event_bus/instance.rb
|
172
|
+
- lib/ribbon/event_bus/mixins.rb
|
173
|
+
- lib/ribbon/event_bus/mixins/has_config.rb
|
174
|
+
- lib/ribbon/event_bus/mixins/has_instance.rb
|
175
|
+
- lib/ribbon/event_bus/mixins/serializable.rb
|
176
|
+
- lib/ribbon/event_bus/plugins.rb
|
177
|
+
- lib/ribbon/event_bus/plugins/logging_plugin.rb
|
178
|
+
- lib/ribbon/event_bus/plugins/plugin.rb
|
179
|
+
- lib/ribbon/event_bus/publishers.rb
|
180
|
+
- lib/ribbon/event_bus/publishers/async_resque_publisher.rb
|
181
|
+
- lib/ribbon/event_bus/publishers/proc_publisher.rb
|
182
|
+
- lib/ribbon/event_bus/publishers/publisher.rb
|
183
|
+
- lib/ribbon/event_bus/publishers/remote_resque_publisher.rb
|
184
|
+
- lib/ribbon/event_bus/publishers/resque_publisher.rb
|
185
|
+
- lib/ribbon/event_bus/publishers/subscriptions_publisher.rb
|
186
|
+
- lib/ribbon/event_bus/subscription.rb
|
187
|
+
- lib/ribbon/event_bus/version.rb
|
188
|
+
homepage: http://github.com/ribbon/event_bus
|
189
|
+
licenses:
|
190
|
+
- BSD
|
191
|
+
metadata: {}
|
192
|
+
post_install_message:
|
193
|
+
rdoc_options: []
|
194
|
+
require_paths:
|
195
|
+
- lib
|
196
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
202
|
+
requirements:
|
203
|
+
- - ">="
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
requirements: []
|
207
|
+
rubyforge_project:
|
208
|
+
rubygems_version: 2.4.3
|
209
|
+
signing_key:
|
210
|
+
specification_version: 4
|
211
|
+
summary: An asynchronous event bus for Ruby.
|
212
|
+
test_files: []
|