banter 1.0.5 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/banter/configuration.rb +4 -8
- data/lib/banter/publisher.rb +5 -3
- data/lib/banter/railtie.rb +1 -0
- data/lib/banter/server/client_queue_listener.rb +4 -4
- data/lib/banter/server/rabbit_mq_subscriber.rb +30 -16
- data/lib/banter/server/subscriber_server.rb +6 -9
- data/lib/banter/subscriber.rb +23 -7
- data/lib/banter/version.rb +1 -1
- data/spec/banter/publisher_spec.rb +20 -1
- data/spec/banter/server/client_queue_listener_spec.rb +3 -1
- data/spec/banter/server/rabbitmq_subscriber_spec.rb +21 -1
- data/spec/banter/server/subscriber_server_spec.rb +5 -2
- data/spec/banter/subscriber_spec.rb +15 -12
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7eddb3c0d8d9801ac79fe7b7ca04c7f892a4cc0a
|
4
|
+
data.tar.gz: 03fd47b4fe7849b469ace3f1b94ca3640857cd6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb0cf4082a90fd66772bb400106d77a2898557984b67b25a2363234b2ee5959ea199b80b41397098dbb1488d449d6178268f6af24e48722c8a71716ddfe4c2f9
|
7
|
+
data.tar.gz: f70da6ed9736961564bb996489927b4d5835005b11d57ac8c2ace0c11915747a63bcf1e244fb0f49549c91af72d7ec86537a365b00db6c282c00eb00ae75f2f9
|
data/lib/banter/configuration.rb
CHANGED
@@ -6,7 +6,7 @@ module Banter
|
|
6
6
|
# being either consumed or discarded.
|
7
7
|
# @default 1 hour
|
8
8
|
mattr_accessor :default_queue_ttl
|
9
|
-
@@default_queue_ttl =
|
9
|
+
@@default_queue_ttl = 36000 # 10 hours in seconds
|
10
10
|
|
11
11
|
# The exchange to publish (and subscribe) on RabbitMQ
|
12
12
|
# @default true
|
@@ -44,6 +44,9 @@ module Banter
|
|
44
44
|
mattr_accessor :web_enabled
|
45
45
|
@@web_enabled = false
|
46
46
|
|
47
|
+
mattr_accessor :application_name
|
48
|
+
@@application_name = nil
|
49
|
+
|
47
50
|
def self.configure_with(environment_name, yaml_file = nil)
|
48
51
|
@@yaml_file = yaml_file.nil? ? "config/banter.yml" : yaml_file
|
49
52
|
@@all_conf = Hashie::Mash.new(YAML.load_file(@@yaml_file) )
|
@@ -73,12 +76,5 @@ module Banter
|
|
73
76
|
end
|
74
77
|
end
|
75
78
|
|
76
|
-
def self.application_name
|
77
|
-
@application_name ||= if defined?(Rails)
|
78
|
-
Rails.application.class.name.to_s.gsub("::Application", '')
|
79
|
-
else
|
80
|
-
'banter'
|
81
|
-
end.downcase
|
82
|
-
end
|
83
79
|
end
|
84
80
|
end
|
data/lib/banter/publisher.rb
CHANGED
@@ -104,9 +104,11 @@ module Banter
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def teardown
|
107
|
-
|
108
|
-
|
109
|
-
|
107
|
+
begin
|
108
|
+
@connection.close
|
109
|
+
rescue => e
|
110
|
+
Banter::RabbitLogger.log(Logger::WARN, "RabbitMQ teardown failed: #{e.message}: #{e.backtrace}")
|
111
|
+
end
|
110
112
|
@publisher = nil
|
111
113
|
end
|
112
114
|
|
data/lib/banter/railtie.rb
CHANGED
@@ -13,6 +13,7 @@ module Banter
|
|
13
13
|
config.after_initialize do
|
14
14
|
Banter.logger = config.banter.logger if config.banter.logger
|
15
15
|
|
16
|
+
Banter::Configuration.application_name = Rails.application.class.name.to_s.gsub("::Application", '').downcase
|
16
17
|
if Banter::Configuration.web_enabled
|
17
18
|
require 'banter/web'
|
18
19
|
end
|
@@ -10,17 +10,17 @@ module Banter
|
|
10
10
|
|
11
11
|
attr_reader :worker_class
|
12
12
|
|
13
|
-
def initialize(worker_class, request_key,
|
13
|
+
def initialize(worker_class, request_key, queue_name, durable = true, topic = nil)
|
14
14
|
@topic = topic || Banter::Configuration.topic_prefix
|
15
15
|
@request_key = request_key
|
16
16
|
@worker_class = worker_class
|
17
|
-
@queue_name = queue
|
18
17
|
@durable = durable
|
19
|
-
@
|
18
|
+
@queue_name = queue_name
|
19
|
+
@subscriber = ::Banter::Server::RabbitMQSubscriber.new(@request_key, @queue_name, worker_class.queue_ttl, @durable, @topic)
|
20
20
|
end
|
21
21
|
|
22
22
|
def start
|
23
|
-
@subscriber.start(
|
23
|
+
@subscriber.start(false) do |delivery_info, properties, envelope|
|
24
24
|
message_received(delivery_info, properties, envelope)
|
25
25
|
true
|
26
26
|
end
|
@@ -7,7 +7,7 @@ module Banter
|
|
7
7
|
attr_reader :channel
|
8
8
|
attr_reader :ttl
|
9
9
|
|
10
|
-
def initialize(routing_key, ttl, durable = true, topic = Banter::Configuration.topic_prefix)
|
10
|
+
def initialize(routing_key, queue_name, ttl, durable = true, topic = Banter::Configuration.topic_prefix)
|
11
11
|
@initial_key = routing_key
|
12
12
|
@durable = durable
|
13
13
|
@topic = topic
|
@@ -18,12 +18,13 @@ module Banter
|
|
18
18
|
else
|
19
19
|
@routing_key = "#{@topic}.#"
|
20
20
|
end
|
21
|
+
|
22
|
+
@queue_name = queue_name
|
21
23
|
end
|
22
24
|
|
23
|
-
# name - used to ensure that certain consumers are actually listening to an exchange
|
24
25
|
# pass in a lambda for this method to work. We might only want to expose the content instead of
|
25
26
|
# all 3 chunks.
|
26
|
-
def start(
|
27
|
+
def start(blocking=false)
|
27
28
|
@connection = Bunny.new(Configuration.connection)
|
28
29
|
begin
|
29
30
|
@connection.start
|
@@ -35,23 +36,29 @@ module Banter
|
|
35
36
|
@channel = @connection.create_channel
|
36
37
|
@exchange = @channel.topic(@topic, :durable => @durable, :auto_delete => false)
|
37
38
|
|
38
|
-
# FIX!!! -thl
|
39
|
-
# Need to ensure that the ids for a server will be reproducible in case a server
|
40
|
-
# goes down and has to get restarted.
|
41
|
-
if @initial_key.present?
|
42
|
-
@queue = "#{@initial_key}.#{name}"
|
43
|
-
else
|
44
|
-
@queue = "#{name}"
|
45
|
-
end
|
46
|
-
|
47
39
|
queue_arguments = {}
|
48
40
|
queue_arguments["x-dead-letter-exchange"] = Configuration.dead_letter_queue if Configuration.dead_letter_queue.present?
|
49
41
|
queue_arguments["x-message-ttl"] = ttl * 1000
|
50
|
-
|
42
|
+
|
43
|
+
# FIX!!! -thl
|
44
|
+
# Something is wrong with basic_qos because the server cannot be quickly bounced when this happens, and for messages to be
|
45
|
+
# quickly picked up. It seems sporadic. It could be a timing thing but I am unsure.
|
46
|
+
# Only grab 1 message at a time, otherwise, we will have to write some extra conditions to reject
|
47
|
+
# all the other messages that they already pulled down, which then could make the subscriber
|
48
|
+
# run out of memory, etc
|
49
|
+
# @channel.basic_qos(1)
|
50
|
+
|
51
|
+
# Need to mark the queue as durable
|
52
|
+
rabbit_queue = @channel.queue(@queue_name, durable: @durable, exclusive: false, arguments: queue_arguments)
|
53
|
+
# rabbit_queue = @channel.queue(@queue_name, arguments: queue_arguments)
|
54
|
+
|
55
|
+
@listener = rabbit_queue.bind(@exchange, routing_key: @routing_key, exclusive: false)
|
51
56
|
|
52
57
|
# Parameters for subscribe that might be useful:
|
53
58
|
# :block=>true - Used for long running consumer applications. (backend servers?)
|
54
|
-
|
59
|
+
|
60
|
+
@consumer = @listener.subscribe(consumer_tag: @queue_name, manual_ack: true, block: blocking)
|
61
|
+
# @consumer = @listener.subscribe(consumer_tag: @queue_name, block: blocking)
|
55
62
|
|
56
63
|
@consumer.on_delivery do |delivery_info, properties, contents|
|
57
64
|
Banter::RabbitLogger.log(Logger::DEBUG, "Message delivery with contents: #{contents}")
|
@@ -63,13 +70,20 @@ module Banter
|
|
63
70
|
Banter::RabbitLogger.log_receive(delivery_info[:routing_key], message)
|
64
71
|
yield delivery_info, properties, message
|
65
72
|
Banter::RabbitLogger.log_complete(delivery_info[:routing_key], message)
|
73
|
+
Banter::RabbitLogger.log(Logger::DEBUG, "Message acknowledged with tag #{delivery_info.delivery_tag}")
|
74
|
+
# Need to acknowledge the message for the next message to come down.
|
75
|
+
@channel.ack(delivery_info.delivery_tag)
|
66
76
|
true
|
67
77
|
end
|
68
78
|
end
|
69
79
|
|
70
80
|
def teardown
|
71
|
-
|
72
|
-
|
81
|
+
begin
|
82
|
+
@consumer.cancel if @consumer.present?
|
83
|
+
@connection.close if @connection.present?
|
84
|
+
rescue => e
|
85
|
+
Airbrake.notify(e, params: { error: e.message }, environment_name: ENV['RAILS_ENV'], backtrace: caller)
|
86
|
+
end
|
73
87
|
end
|
74
88
|
end
|
75
89
|
end
|
@@ -88,7 +88,6 @@ module Banter
|
|
88
88
|
Banter::CLI.instance.remove_pid
|
89
89
|
end
|
90
90
|
|
91
|
-
|
92
91
|
def set_information
|
93
92
|
@process_name = $0
|
94
93
|
@pid = Process.pid
|
@@ -96,15 +95,13 @@ module Banter
|
|
96
95
|
end
|
97
96
|
|
98
97
|
def create_queue_listeners(subscriber)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
raise ArgumentError.new("Queue Name must be provided in #{subscriber.name} using `subscribe_to routing_key, on: queue_name`")
|
104
|
-
end
|
98
|
+
application_name = Banter::Configuration.application_name
|
99
|
+
routing_key = subscriber.subscribed_key
|
100
|
+
durable = subscriber.durable
|
101
|
+
queue_name = subscriber.generated_queue_name(routing_key, application_name)
|
105
102
|
|
106
|
-
STDOUT.puts "Setting up listener for request_key: #{routing_key} and queue:#{
|
107
|
-
ClientQueueListener.new(subscriber, routing_key,
|
103
|
+
STDOUT.puts "Setting up listener for request_key: #{routing_key} and queue:#{application_name}"
|
104
|
+
ClientQueueListener.new(subscriber, routing_key, queue_name, durable)
|
108
105
|
end
|
109
106
|
end
|
110
107
|
end
|
data/lib/banter/subscriber.rb
CHANGED
@@ -8,7 +8,7 @@ module Banter
|
|
8
8
|
class Subscriber
|
9
9
|
@@registered_subscribers = []
|
10
10
|
|
11
|
-
class_attribute :payload_validators, :error_handlers, :subscribed_key, :subscribed_queue, :queue_ttl
|
11
|
+
class_attribute :payload_validators, :error_handlers, :subscribed_key, :subscribed_queue, :queue_ttl, :application_name, :durable
|
12
12
|
attr_accessor :delivery_routing_data, :delivery_properties, :context
|
13
13
|
|
14
14
|
def self.inherited(klass)
|
@@ -18,18 +18,20 @@ module Banter
|
|
18
18
|
# Specify the routing key that the subscriber class should listen to.
|
19
19
|
# @param [String] routing_key_name The routing key to subscribe to. Must be characters only separated by periods (.)
|
20
20
|
# @param [Hash] options subscription options
|
21
|
-
# @option [String] :
|
21
|
+
# @option [String] :durable sets the subscriber to be a durable subscriber (one that survives reboots). This currently defaults to true.
|
22
22
|
# @option [Integer] :queue_ttl Time, in seconds, that the message lives on the queue before being either consumer by a subscriber or being discarded.
|
23
23
|
# If not specified, then Banter::Configuration.default_queue_ttl is used
|
24
24
|
|
25
25
|
def self.subscribe_to(routing_key_name, options = {})
|
26
|
-
options.assert_valid_keys(:
|
26
|
+
options.assert_valid_keys(:durable, :queue_ttl)
|
27
27
|
unless validate_routing_key_name(routing_key_name)
|
28
28
|
raise ArgumentError.new("#{routing_key_name} is not supported. Only lower case characters separated by periods are allowed.")
|
29
29
|
end
|
30
30
|
self.subscribed_key = routing_key_name
|
31
|
-
self.
|
31
|
+
self.application_name = generated_application_name(options[:on])
|
32
|
+
self.subscribed_queue = generated_queue_name(routing_key_name, self.application_name)
|
32
33
|
self.queue_ttl = options[:queue_ttl] || Banter::Configuration.default_queue_ttl
|
34
|
+
self.durable = options.key?(:durable) ? options[:durable] : true
|
33
35
|
end
|
34
36
|
|
35
37
|
# Sets the validator for payload
|
@@ -113,9 +115,23 @@ module Banter
|
|
113
115
|
key.match(/\A([a-z_]+\.?)*([a-z\_]+)\Z/).present?
|
114
116
|
end
|
115
117
|
|
116
|
-
def self.
|
117
|
-
return
|
118
|
-
|
118
|
+
def self.generated_application_name(application_name)
|
119
|
+
return application_name if application_name.present?
|
120
|
+
|
121
|
+
Banter::Configuration.application_name.to_s.gsub(/[^\w\_ ]/, '')
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.generated_queue_name(routing_key, application_name)
|
125
|
+
name = ""
|
126
|
+
if routing_key.present?
|
127
|
+
name = routing_key
|
128
|
+
if application_name
|
129
|
+
name += "_#{application_name}"
|
130
|
+
end
|
131
|
+
else
|
132
|
+
name = application_name
|
133
|
+
end
|
134
|
+
name
|
119
135
|
end
|
120
136
|
|
121
137
|
end
|
data/lib/banter/version.rb
CHANGED
@@ -49,7 +49,7 @@ describe Banter::Publisher do
|
|
49
49
|
|
50
50
|
specify {expect { result }.not_to raise_error }
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
context "duplicate entries" do
|
54
54
|
let(:result) { publisher.delay_messages { operations } }
|
55
55
|
|
@@ -88,4 +88,23 @@ describe Banter::Publisher do
|
|
88
88
|
end
|
89
89
|
|
90
90
|
end
|
91
|
+
|
92
|
+
describe "#teardown" do
|
93
|
+
context "should not fail" do
|
94
|
+
before do
|
95
|
+
allow(Banter::RabbitLogger).to receive(:log).with(Logger::WARN, /RabbitMQ teardown failed/)
|
96
|
+
end
|
97
|
+
|
98
|
+
it do
|
99
|
+
expect{publisher.send(:teardown)}.not_to raise_error
|
100
|
+
end
|
101
|
+
|
102
|
+
it do
|
103
|
+
publisher.send(:teardown)
|
104
|
+
expect(Banter::RabbitLogger).to have_received(:log).exactly(1).times
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
91
110
|
end
|
@@ -15,6 +15,7 @@ describe Banter::Server::ClientQueueListener do
|
|
15
15
|
Banter::Configuration.web_enabled = true
|
16
16
|
allow(BanterWorker).to receive(:current).and_return(banter_worker)
|
17
17
|
}
|
18
|
+
let!(:application_name) { "testapplication" }
|
18
19
|
let(:banter_message) { BanterMessage.last }
|
19
20
|
|
20
21
|
after(:each) { Banter::Configuration.web_enabled = false }
|
@@ -22,7 +23,7 @@ describe Banter::Server::ClientQueueListener do
|
|
22
23
|
def self.banter_message_fields_are_correct(status, error_message = nil)
|
23
24
|
it { expect(BanterMessage.count).to eq 1 }
|
24
25
|
it { expect(banter_message.subscriber_class).to eq('Klass') }
|
25
|
-
it { expect(banter_message.queue_name).to eq(
|
26
|
+
it { expect(banter_message.queue_name).to eq("test.foo_#{application_name}") }
|
26
27
|
it { expect(banter_message.subscribed_key).to eq('test.foo') }
|
27
28
|
it { expect(banter_message.payload).to eq({ "hello" => "moto" }) }
|
28
29
|
it { expect(banter_message.started_at.to_s).to eq(Time.now.to_s) }
|
@@ -39,6 +40,7 @@ describe Banter::Server::ClientQueueListener do
|
|
39
40
|
end
|
40
41
|
|
41
42
|
before do
|
43
|
+
Banter::Configuration.application_name = application_name
|
42
44
|
context_before
|
43
45
|
Object.const_set :Klass, Class.new(Banter::Subscriber)
|
44
46
|
validators.each do |validator|
|
@@ -1,5 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Banter::Server::RabbitMQSubscriber do
|
4
|
-
|
4
|
+
let(:durable) { true }
|
5
|
+
let(:routing_key) { 'test.me' }
|
6
|
+
let(:application_name) { 'queue_spec'}
|
7
|
+
let(:queue_name) { "test.me_#{application_name}" }
|
8
|
+
let(:ttl) { 100000 }
|
9
|
+
subject { Banter::Server::RabbitMQSubscriber.new( routing_key, queue_name, ttl, durable) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
Banter::Configuration.application_name = application_name
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#start" do
|
16
|
+
before do
|
17
|
+
end
|
18
|
+
|
19
|
+
context "mark queue as durable" do
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
5
25
|
end
|
@@ -5,15 +5,18 @@ require 'spec_helper'
|
|
5
5
|
|
6
6
|
describe Banter::Server::SubscriberServer do
|
7
7
|
subject { Banter::Server::SubscriberServer.instance }
|
8
|
+
let!(:application_name) { "testsubscriber" }
|
9
|
+
let!(:durable) { true }
|
8
10
|
describe '#set_workers' do
|
9
11
|
before {
|
12
|
+
Banter::Configuration.application_name = application_name
|
10
13
|
allow(Banter::Server::ClientQueueListener).to receive(:new)
|
11
14
|
subject.set_workers([MyTestSubscriber1, MyTestSubscriber2])
|
12
15
|
}
|
13
16
|
|
14
17
|
it "creates queue listeners" do
|
15
|
-
expect(Banter::Server::ClientQueueListener).to have_received(:new).with(MyTestSubscriber1, "foo.bar.one",
|
16
|
-
expect(Banter::Server::ClientQueueListener).to have_received(:new).with(MyTestSubscriber2, "foo.bar.two",
|
18
|
+
expect(Banter::Server::ClientQueueListener).to have_received(:new).with(MyTestSubscriber1, "foo.bar.one", "foo.bar.one_#{application_name}", durable)
|
19
|
+
expect(Banter::Server::ClientQueueListener).to have_received(:new).with(MyTestSubscriber2, "foo.bar.two", "foo.bar.two_#{application_name}", durable)
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
@@ -3,6 +3,11 @@ require 'spec_helper'
|
|
3
3
|
describe Banter::Subscriber do
|
4
4
|
before(:each) { Object.const_set :Klass, Class.new(Banter::Subscriber) }
|
5
5
|
after(:each) { Object.send :remove_const, :Klass }
|
6
|
+
let!(:application_name) { "app_name"}
|
7
|
+
|
8
|
+
before do
|
9
|
+
Banter::Configuration.application_name = application_name
|
10
|
+
end
|
6
11
|
|
7
12
|
describe "#routing_key" do
|
8
13
|
subject { Banter::Subscriber.new(routing_data, properties, {}).routing_key }
|
@@ -205,44 +210,42 @@ describe Banter::Subscriber do
|
|
205
210
|
end
|
206
211
|
|
207
212
|
describe "#generated_queue_name" do
|
208
|
-
before(:each) { allow(Banter::Configuration).to receive(:application_name).and_return("app_name")}
|
209
213
|
|
210
|
-
it { expect(Klass.send(:generated_queue_name, 'abcdef', 'queue_name')).to eq('
|
211
|
-
it { expect(Klass.send(:generated_queue_name, 'abcdef', nil)).to eq('
|
212
|
-
it { expect(Klass.send(:generated_queue_name, 'abcdef.abcd', nil)).to eq('
|
213
|
-
it { expect(Klass.send(:generated_queue_name, 'a.b.c', nil)).to eq('
|
214
|
+
it { expect(Klass.send(:generated_queue_name, 'abcdef', 'queue_name')).to eq('abcdef_queue_name') }
|
215
|
+
it { expect(Klass.send(:generated_queue_name, 'abcdef', nil)).to eq('abcdef') }
|
216
|
+
it { expect(Klass.send(:generated_queue_name, 'abcdef.abcd', nil)).to eq('abcdef.abcd') }
|
217
|
+
it { expect(Klass.send(:generated_queue_name, 'a.b.c', nil)).to eq('a.b.c') }
|
214
218
|
end
|
215
219
|
|
216
220
|
describe '.subscribe_to' do
|
217
|
-
before(:each) { allow(Banter::Configuration).to receive(:application_name).and_return("app_name")}
|
218
221
|
context 'routing_key without queue_name' do
|
219
222
|
before { Klass.subscribe_to 'a.b.c' }
|
220
223
|
it 'sets the routing key and queue name' do
|
221
224
|
expect(Klass.subscribed_key).to eq('a.b.c')
|
222
|
-
expect(Klass.subscribed_queue).to eq('
|
225
|
+
expect(Klass.subscribed_queue).to eq('a.b.c_app_name')
|
223
226
|
end
|
224
227
|
end
|
225
228
|
|
226
229
|
context 'routing_key with queue_name' do
|
227
|
-
before { Klass.subscribe_to 'a.b.c'
|
230
|
+
before { Klass.subscribe_to 'a.b.c' }
|
228
231
|
it 'sets the routing key and queue name' do
|
229
232
|
expect(Klass.subscribed_key).to eq('a.b.c')
|
230
|
-
expect(Klass.subscribed_queue).to eq('
|
233
|
+
expect(Klass.subscribed_queue).to eq('a.b.c_app_name')
|
231
234
|
end
|
232
235
|
end
|
233
236
|
|
234
237
|
context 'underscore in routing key' do
|
235
|
-
before { Klass.subscribe_to 'a_b.c'
|
238
|
+
before { Klass.subscribe_to 'a_b.c' }
|
236
239
|
it 'is allowed' do
|
237
240
|
expect(Klass.subscribed_key).to eq('a_b.c')
|
238
|
-
expect(Klass.subscribed_queue).to eq('
|
241
|
+
expect(Klass.subscribed_queue).to eq('a_b.c_app_name')
|
239
242
|
end
|
240
243
|
end
|
241
244
|
|
242
245
|
context 'invalid routing key' do
|
243
246
|
it 'sets the routing key and queue name' do
|
244
247
|
expect {
|
245
|
-
Klass.subscribe_to 'a.b.c.'
|
248
|
+
Klass.subscribe_to 'a.b.c.'
|
246
249
|
}.to raise_error(ArgumentError)
|
247
250
|
end
|
248
251
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: banter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Honest Company
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2014-
|
14
|
+
date: 2014-09-18 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -288,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
288
288
|
version: '0'
|
289
289
|
requirements: []
|
290
290
|
rubyforge_project:
|
291
|
-
rubygems_version: 2.
|
291
|
+
rubygems_version: 2.2.2
|
292
292
|
signing_key:
|
293
293
|
specification_version: 4
|
294
294
|
summary: Library for pub-sub (Message Bus)
|