rabbit_feed 0.3.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/.gitignore +11 -0
- data/.rspec +3 -0
- data/Brewfile +4 -0
- data/DEVELOPING.md +140 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +121 -0
- data/LICENSE.txt +9 -0
- data/README.md +304 -0
- data/Rakefile +30 -0
- data/bin/bundle +3 -0
- data/bin/rabbit_feed +11 -0
- data/example/non_rails_app/.rspec +1 -0
- data/example/non_rails_app/Gemfile +7 -0
- data/example/non_rails_app/Gemfile.lock +56 -0
- data/example/non_rails_app/Rakefile +5 -0
- data/example/non_rails_app/bin/benchmark +63 -0
- data/example/non_rails_app/bin/bundle +3 -0
- data/example/non_rails_app/config/rabbit_feed.yml +8 -0
- data/example/non_rails_app/lib/non_rails_app.rb +32 -0
- data/example/non_rails_app/lib/non_rails_app/event_handler.rb +10 -0
- data/example/non_rails_app/log/.keep +0 -0
- data/example/non_rails_app/spec/lib/non_rails_app/event_handler_spec.rb +14 -0
- data/example/non_rails_app/spec/lib/non_rails_app/event_routing_spec.rb +14 -0
- data/example/non_rails_app/spec/spec_helper.rb +31 -0
- data/example/non_rails_app/tmp/pids/.keep +0 -0
- data/example/rails_app/.gitignore +17 -0
- data/example/rails_app/.node-version +1 -0
- data/example/rails_app/.rspec +1 -0
- data/example/rails_app/Gemfile +36 -0
- data/example/rails_app/Gemfile.lock +173 -0
- data/example/rails_app/README.rdoc +28 -0
- data/example/rails_app/Rakefile +6 -0
- data/example/rails_app/app/assets/images/.keep +0 -0
- data/example/rails_app/app/assets/javascripts/application.js +16 -0
- data/example/rails_app/app/assets/javascripts/beavers.js.coffee +3 -0
- data/example/rails_app/app/assets/stylesheets/application.css +15 -0
- data/example/rails_app/app/assets/stylesheets/beavers.css.scss +3 -0
- data/example/rails_app/app/assets/stylesheets/scaffolds.css.scss +69 -0
- data/example/rails_app/app/controllers/application_controller.rb +5 -0
- data/example/rails_app/app/controllers/beavers_controller.rb +81 -0
- data/example/rails_app/app/controllers/concerns/.keep +0 -0
- data/example/rails_app/app/helpers/application_helper.rb +2 -0
- data/example/rails_app/app/helpers/beavers_helper.rb +2 -0
- data/example/rails_app/app/mailers/.keep +0 -0
- data/example/rails_app/app/models/.keep +0 -0
- data/example/rails_app/app/models/beaver.rb +2 -0
- data/example/rails_app/app/models/concerns/.keep +0 -0
- data/example/rails_app/app/views/beavers/_form.html.erb +21 -0
- data/example/rails_app/app/views/beavers/edit.html.erb +6 -0
- data/example/rails_app/app/views/beavers/index.html.erb +25 -0
- data/example/rails_app/app/views/beavers/index.json.jbuilder +4 -0
- data/example/rails_app/app/views/beavers/new.html.erb +5 -0
- data/example/rails_app/app/views/beavers/show.html.erb +9 -0
- data/example/rails_app/app/views/beavers/show.json.jbuilder +1 -0
- data/example/rails_app/app/views/layouts/application.html.erb +14 -0
- data/example/rails_app/bin/bundle +3 -0
- data/example/rails_app/bin/rails +4 -0
- data/example/rails_app/bin/rake +4 -0
- data/example/rails_app/config.ru +4 -0
- data/example/rails_app/config/application.rb +25 -0
- data/example/rails_app/config/boot.rb +4 -0
- data/example/rails_app/config/database.yml +22 -0
- data/example/rails_app/config/environment.rb +5 -0
- data/example/rails_app/config/environments/development.rb +83 -0
- data/example/rails_app/config/environments/test.rb +39 -0
- data/example/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/example/rails_app/config/initializers/cookies_serializer.rb +3 -0
- data/example/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/example/rails_app/config/initializers/inflections.rb +16 -0
- data/example/rails_app/config/initializers/mime_types.rb +4 -0
- data/example/rails_app/config/initializers/rabbit_feed.rb +43 -0
- data/example/rails_app/config/initializers/session_store.rb +3 -0
- data/example/rails_app/config/initializers/wrap_parameters.rb +14 -0
- data/example/rails_app/config/locales/en.yml +23 -0
- data/example/rails_app/config/rabbit_feed.yml +8 -0
- data/example/rails_app/config/routes.rb +58 -0
- data/example/rails_app/config/secrets.yml +18 -0
- data/example/rails_app/config/unicorn.rb +4 -0
- data/example/rails_app/db/migrate/20140424102400_create_beavers.rb +9 -0
- data/example/rails_app/db/schema.rb +22 -0
- data/example/rails_app/db/seeds.rb +7 -0
- data/example/rails_app/lib/assets/.keep +0 -0
- data/example/rails_app/lib/event_handler.rb +7 -0
- data/example/rails_app/lib/tasks/.keep +0 -0
- data/example/rails_app/log/.keep +0 -0
- data/example/rails_app/public/404.html +67 -0
- data/example/rails_app/public/422.html +67 -0
- data/example/rails_app/public/500.html +66 -0
- data/example/rails_app/public/favicon.ico +0 -0
- data/example/rails_app/public/robots.txt +5 -0
- data/example/rails_app/spec/controllers/beavers_controller_spec.rb +32 -0
- data/example/rails_app/spec/event_routing_spec.rb +15 -0
- data/example/rails_app/spec/spec_helper.rb +51 -0
- data/example/rails_app/test/controllers/.keep +0 -0
- data/example/rails_app/test/controllers/beavers_controller_test.rb +49 -0
- data/example/rails_app/test/fixtures/.keep +0 -0
- data/example/rails_app/test/fixtures/beavers.yml +7 -0
- data/example/rails_app/test/helpers/.keep +0 -0
- data/example/rails_app/test/helpers/beavers_helper_test.rb +4 -0
- data/example/rails_app/test/integration/.keep +0 -0
- data/example/rails_app/test/mailers/.keep +0 -0
- data/example/rails_app/test/models/.keep +0 -0
- data/example/rails_app/test/models/beaver_test.rb +7 -0
- data/example/rails_app/test/test_helper.rb +13 -0
- data/example/rails_app/tmp/pids/.keep +0 -0
- data/example/rails_app/vendor/assets/javascripts/.keep +0 -0
- data/example/rails_app/vendor/assets/stylesheets/.keep +0 -0
- data/lib/dsl.rb +9 -0
- data/lib/rabbit_feed.rb +41 -0
- data/lib/rabbit_feed/client.rb +181 -0
- data/lib/rabbit_feed/configuration.rb +50 -0
- data/lib/rabbit_feed/connection_concern.rb +95 -0
- data/lib/rabbit_feed/consumer.rb +14 -0
- data/lib/rabbit_feed/consumer_connection.rb +108 -0
- data/lib/rabbit_feed/event.rb +43 -0
- data/lib/rabbit_feed/event_definitions.rb +98 -0
- data/lib/rabbit_feed/event_routing.rb +90 -0
- data/lib/rabbit_feed/producer.rb +47 -0
- data/lib/rabbit_feed/producer_connection.rb +65 -0
- data/lib/rabbit_feed/testing_support/rspec_matchers/publish_event.rb +90 -0
- data/lib/rabbit_feed/testing_support/testing_helpers.rb +16 -0
- data/lib/rabbit_feed/version.rb +3 -0
- data/logo.png +0 -0
- data/rabbit_feed.gemspec +35 -0
- data/run_benchmark +35 -0
- data/run_example +62 -0
- data/run_recovery_test +26 -0
- data/spec/features/connectivity.feature +13 -0
- data/spec/features/step_definitions/connectivity_steps.rb +96 -0
- data/spec/fixtures/configuration.yml +14 -0
- data/spec/lib/rabbit_feed/client_spec.rb +116 -0
- data/spec/lib/rabbit_feed/configuration_spec.rb +121 -0
- data/spec/lib/rabbit_feed/connection_concern_spec.rb +116 -0
- data/spec/lib/rabbit_feed/consumer_connection_spec.rb +85 -0
- data/spec/lib/rabbit_feed/event_definitions_spec.rb +139 -0
- data/spec/lib/rabbit_feed/event_routing_spec.rb +121 -0
- data/spec/lib/rabbit_feed/event_spec.rb +33 -0
- data/spec/lib/rabbit_feed/producer_connection_spec.rb +72 -0
- data/spec/lib/rabbit_feed/producer_spec.rb +57 -0
- data/spec/lib/rabbit_feed/testing_support/rspec_matchers/publish_event_spec.rb +60 -0
- data/spec/lib/rabbit_feed/testing_support/testing_helper_spec.rb +34 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/support/shared_examples_for_connections.rb +40 -0
- metadata +305 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
test:
|
|
2
|
+
host: localhost
|
|
3
|
+
port: 5672
|
|
4
|
+
user: guest
|
|
5
|
+
password: guest
|
|
6
|
+
application: rabbit_feed
|
|
7
|
+
exchange: rabbit_feed_exchange
|
|
8
|
+
pool_size: 1
|
|
9
|
+
pool_timeout: 1
|
|
10
|
+
heartbeat: 60
|
|
11
|
+
connect_timeout: 1
|
|
12
|
+
network_recovery_interval: 0.1
|
|
13
|
+
auto_delete_queue: true
|
|
14
|
+
auto_delete_exchange: true
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module RabbitFeed
|
|
4
|
+
describe Client do
|
|
5
|
+
let(:command) { 'consume' }
|
|
6
|
+
let(:logfile) { 'test.log' }
|
|
7
|
+
let(:pidfile) { './test.pid' }
|
|
8
|
+
let(:config_file) { 'spec/fixtures/configuration.yml' }
|
|
9
|
+
let(:environment) { 'test' }
|
|
10
|
+
let(:require_file){ 'rabbit_feed.rb' }
|
|
11
|
+
let(:arguments) do
|
|
12
|
+
[
|
|
13
|
+
command,
|
|
14
|
+
'--environment',
|
|
15
|
+
environment,
|
|
16
|
+
'--config',
|
|
17
|
+
config_file,
|
|
18
|
+
'--logfile',
|
|
19
|
+
logfile,
|
|
20
|
+
'--pidfile',
|
|
21
|
+
pidfile,
|
|
22
|
+
'--require',
|
|
23
|
+
require_file,
|
|
24
|
+
'--daemon'
|
|
25
|
+
]
|
|
26
|
+
end
|
|
27
|
+
before do
|
|
28
|
+
RabbitFeed.environment = nil
|
|
29
|
+
RabbitFeed.log = nil
|
|
30
|
+
RabbitFeed.configuration_file_path = nil
|
|
31
|
+
end
|
|
32
|
+
subject{ described_class.new arguments }
|
|
33
|
+
|
|
34
|
+
describe '.new' do
|
|
35
|
+
|
|
36
|
+
it { should be_valid }
|
|
37
|
+
|
|
38
|
+
it 'sets the environment' do
|
|
39
|
+
subject
|
|
40
|
+
expect(RabbitFeed.environment).to eq 'test'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'sets the logger' do
|
|
44
|
+
subject
|
|
45
|
+
expect(RabbitFeed.log).to be_a Logger
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'sets the configuration' do
|
|
49
|
+
subject
|
|
50
|
+
expect(RabbitFeed.configuration).to be_a Configuration
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context 'when the command is invalid' do
|
|
54
|
+
let(:command) { 'blah' }
|
|
55
|
+
|
|
56
|
+
it 'should be invalid' do
|
|
57
|
+
expect{subject}.to raise_error Error
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context 'when the log file path is not present' do
|
|
62
|
+
let(:logfile) { '/blah/blah.log' }
|
|
63
|
+
|
|
64
|
+
it 'should be invalid' do
|
|
65
|
+
expect{subject}.to raise_error Error
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context 'when the pid file path is not present' do
|
|
70
|
+
let(:pidfile) { '/blah/blah.pid' }
|
|
71
|
+
|
|
72
|
+
it 'should be invalid' do
|
|
73
|
+
expect{subject}.to raise_error Error
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'when the config file is not present' do
|
|
78
|
+
let(:config_file) { '/blah/blah.yml' }
|
|
79
|
+
|
|
80
|
+
it 'should be invalid' do
|
|
81
|
+
expect{subject}.to raise_error Error
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context 'when the environment is not present' do
|
|
86
|
+
let(:environment) { '' }
|
|
87
|
+
before do
|
|
88
|
+
ENV['RAILS_ENV'] = nil
|
|
89
|
+
ENV['RACK_ENV'] = nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'should be invalid' do
|
|
93
|
+
expect{subject}.to raise_error Error
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context 'when the RAILS_ENV is present' do
|
|
97
|
+
before { ENV['RAILS_ENV'] = 'test' }
|
|
98
|
+
after do
|
|
99
|
+
ENV['RAILS_ENV'] = nil
|
|
100
|
+
ENV['RACK_ENV'] = nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it { should be_valid }
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'when requiring a directory in a non rails app' do
|
|
108
|
+
let(:require_file) { './' }
|
|
109
|
+
|
|
110
|
+
it 'should be invalid' do
|
|
111
|
+
expect{subject}.to raise_error Error
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module RabbitFeed
|
|
4
|
+
describe Configuration do
|
|
5
|
+
|
|
6
|
+
describe '#queue' do
|
|
7
|
+
let(:options) do
|
|
8
|
+
{
|
|
9
|
+
application: 'rabbit_feed',
|
|
10
|
+
environment: 'test',
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
subject { (described_class.new options).queue }
|
|
14
|
+
|
|
15
|
+
it { should eq 'test.rabbit_feed' }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '.load' do
|
|
19
|
+
let(:file_path) { 'spec/fixtures/configuration.yml' }
|
|
20
|
+
let(:environment) { 'test' }
|
|
21
|
+
subject { described_class.load file_path, environment }
|
|
22
|
+
|
|
23
|
+
context 'with missing configuration' do
|
|
24
|
+
let(:environment) { 'production' }
|
|
25
|
+
|
|
26
|
+
it 'should raise an error' do
|
|
27
|
+
expect{ subject }.to raise_error ConfigurationError
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'with configuration' do
|
|
32
|
+
|
|
33
|
+
its(:host) { should eq 'localhost' }
|
|
34
|
+
its(:port) { should eq 5672 }
|
|
35
|
+
its(:user) { should eq 'guest' }
|
|
36
|
+
its(:password) { should eq 'guest' }
|
|
37
|
+
its(:application) { should eq 'rabbit_feed' }
|
|
38
|
+
its(:environment) { should eq 'test' }
|
|
39
|
+
its(:exchange) { should eq 'rabbit_feed_exchange' }
|
|
40
|
+
its(:pool_size) { should eq 1 }
|
|
41
|
+
its(:pool_timeout) { should eq 1 }
|
|
42
|
+
its(:heartbeat) { should eq 60 }
|
|
43
|
+
its(:connect_timeout) { should eq 1 }
|
|
44
|
+
its(:network_recovery_interval) { should eq 0.1 }
|
|
45
|
+
its(:auto_delete_queue) { should be_true }
|
|
46
|
+
its(:auto_delete_exchange) { should be_true }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe '.new' do
|
|
52
|
+
let(:options) {{}}
|
|
53
|
+
subject { described_class.new options }
|
|
54
|
+
|
|
55
|
+
context 'with default options' do
|
|
56
|
+
let(:options) do
|
|
57
|
+
{
|
|
58
|
+
application: 'rabbit_feed',
|
|
59
|
+
environment: 'test',
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
its(:host) { should eq 'localhost' }
|
|
64
|
+
its(:port) { should eq 5672 }
|
|
65
|
+
its(:user) { should eq 'guest' }
|
|
66
|
+
its(:password) { should eq 'guest' }
|
|
67
|
+
its(:exchange) { should eq 'amq.topic' }
|
|
68
|
+
its(:pool_size) { should eq 1 }
|
|
69
|
+
its(:pool_timeout) { should eq 5 }
|
|
70
|
+
its(:heartbeat) { should eq 5 }
|
|
71
|
+
its(:connect_timeout) { should eq 10 }
|
|
72
|
+
its(:network_recovery_interval) { should eq 1 }
|
|
73
|
+
its(:auto_delete_queue) { should be_false }
|
|
74
|
+
its(:auto_delete_exchange) { should be_false }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'with provided options' do
|
|
78
|
+
let(:options) do
|
|
79
|
+
{
|
|
80
|
+
host: 'host_name',
|
|
81
|
+
port: 12345,
|
|
82
|
+
user: 'user_name',
|
|
83
|
+
password: 'password',
|
|
84
|
+
application: 'rabbit_feed',
|
|
85
|
+
environment: 'test',
|
|
86
|
+
exchange: 'exchange_name',
|
|
87
|
+
pool_size: 2,
|
|
88
|
+
pool_timeout: 6,
|
|
89
|
+
heartbeat: 3,
|
|
90
|
+
connect_timeout: 4,
|
|
91
|
+
network_recovery_interval: 2,
|
|
92
|
+
auto_delete_queue: 'true',
|
|
93
|
+
auto_delete_exchange: 'false',
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
its(:host) { should eq 'host_name' }
|
|
98
|
+
its(:port) { should eq 12345 }
|
|
99
|
+
its(:user) { should eq 'user_name' }
|
|
100
|
+
its(:password) { should eq 'password' }
|
|
101
|
+
its(:application) { should eq 'rabbit_feed' }
|
|
102
|
+
its(:environment) { should eq 'test' }
|
|
103
|
+
its(:exchange) { should eq 'exchange_name' }
|
|
104
|
+
its(:pool_size) { should eq 2 }
|
|
105
|
+
its(:pool_timeout) { should eq 6 }
|
|
106
|
+
its(:heartbeat) { should eq 3 }
|
|
107
|
+
its(:connect_timeout) { should eq 4 }
|
|
108
|
+
its(:network_recovery_interval) { should eq 2 }
|
|
109
|
+
its(:auto_delete_queue) { should be_true }
|
|
110
|
+
its(:auto_delete_exchange) { should be_true }
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context 'with empty options' do
|
|
114
|
+
|
|
115
|
+
it 'should raise an error' do
|
|
116
|
+
expect{ subject }.to raise_error ConfigurationError
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module RabbitFeed
|
|
4
|
+
describe ConnectionConcern do
|
|
5
|
+
let(:bunny_exchange) { double(:bunny_exchange, on_return: nil) }
|
|
6
|
+
let(:connection_closed) { false }
|
|
7
|
+
let(:bunny_channel) { double(:bunny_channel, exchange: bunny_exchange, id: 1) }
|
|
8
|
+
let(:bunny_connection) { double(:bunny_connection, start: nil, closed?: connection_closed, close: nil, create_channel: bunny_channel) }
|
|
9
|
+
before { allow(Bunny).to receive(:new).and_return(bunny_connection) }
|
|
10
|
+
after do
|
|
11
|
+
subject.instance_variable_set(:@bunny_connection, nil)
|
|
12
|
+
subject.instance_variable_set(:@connection_pool, nil)
|
|
13
|
+
end
|
|
14
|
+
subject { RabbitFeed::ProducerConnection }
|
|
15
|
+
|
|
16
|
+
describe '.with_connection' do
|
|
17
|
+
|
|
18
|
+
it 'retries on exception' do
|
|
19
|
+
expect(subject).to receive(:retry_on_exception).and_call_original
|
|
20
|
+
subject.with_connection{|connection| connection }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'assigns the connection' do
|
|
24
|
+
subject.with_connection{|connection| connection }
|
|
25
|
+
expect(subject.instance_variable_get(:@bunny_connection)).to eq bunny_connection
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'assigns the connection pool' do
|
|
29
|
+
subject.with_connection{|connection| connection }
|
|
30
|
+
expect(subject.instance_variable_get(:@connection_pool)).to be_a ConnectionPool
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'provides an instance of the class' do
|
|
34
|
+
actual = subject.with_connection{|connection| connection }
|
|
35
|
+
expect(actual).to be_a subject
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe '.close' do
|
|
40
|
+
|
|
41
|
+
context 'when the connection is nil' do
|
|
42
|
+
|
|
43
|
+
it 'does not close the connection' do
|
|
44
|
+
expect(bunny_connection).not_to receive(:close)
|
|
45
|
+
subject.close
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context 'when the connection is not nil' do
|
|
50
|
+
before do
|
|
51
|
+
subject.with_connection{|connection| connection }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context 'when the connection is closed' do
|
|
55
|
+
let(:connection_closed) { true }
|
|
56
|
+
|
|
57
|
+
it 'does not close the connection' do
|
|
58
|
+
expect(bunny_connection).not_to receive(:close)
|
|
59
|
+
subject.close
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context 'when the connection is not closed' do
|
|
64
|
+
let(:connection_closed) { false }
|
|
65
|
+
|
|
66
|
+
it 'closes the connection' do
|
|
67
|
+
expect(bunny_connection).to receive(:close)
|
|
68
|
+
subject.close
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'when closing raises an exception' do
|
|
72
|
+
|
|
73
|
+
it 'does not propogate the exception' do
|
|
74
|
+
allow(bunny_connection).to receive(:close).and_raise 'error'
|
|
75
|
+
expect{ subject.close }.not_to raise_error
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'unsets the connection' do
|
|
81
|
+
subject.close
|
|
82
|
+
expect(subject.instance_variable_get(:@bunny_connection)).to be_nil
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'unsets the connection pool' do
|
|
86
|
+
subject.close
|
|
87
|
+
expect(subject.instance_variable_get(:@connection_pool)).to be_nil
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe '.retry_on_exception' do
|
|
93
|
+
it_behaves_like 'an operation that retries on exception', :retry_on_exception, RuntimeError
|
|
94
|
+
it_behaves_like 'an operation that does not retry on exception', :retry_on_exception, Bunny::ConnectionClosedError
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe '.retry_on_closed_connection' do
|
|
98
|
+
before do
|
|
99
|
+
subject.with_connection{|connection| connection }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it_behaves_like 'an operation that retries on exception', :retry_on_closed_connection, Bunny::ConnectionClosedError
|
|
103
|
+
it_behaves_like 'an operation that does not retry on exception', :retry_on_closed_connection, RuntimeError
|
|
104
|
+
|
|
105
|
+
it 'unsets the connection' do
|
|
106
|
+
expect { subject.retry_on_closed_connection { raise Bunny::ConnectionClosedError.new 'blah' } }.to raise_error
|
|
107
|
+
expect(subject.instance_variable_get(:@bunny_connection)).to be_nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'unsets the connection pool' do
|
|
111
|
+
expect { subject.retry_on_closed_connection { raise Bunny::ConnectionClosedError.new 'blah' } }.to raise_error
|
|
112
|
+
expect(subject.instance_variable_get(:@connection_pool)).to be_nil
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module RabbitFeed
|
|
4
|
+
describe ConsumerConnection do
|
|
5
|
+
let(:bunny_queue) { double(:bunny_queue, bind: nil, subscribe: nil)}
|
|
6
|
+
let(:bunny_channel) { double(:bunny_channel, prefetch: nil, nack: nil, ack: nil, queue: bunny_queue, id: 1)}
|
|
7
|
+
let(:bunny_connection) { double(:bunny_connection, start: nil, closed?: false, close: nil, create_channel: bunny_channel) }
|
|
8
|
+
before do
|
|
9
|
+
allow(Bunny).to receive(:new).and_return(bunny_connection)
|
|
10
|
+
allow(bunny_queue).to receive(:channel).and_return(bunny_channel)
|
|
11
|
+
end
|
|
12
|
+
subject{ described_class.new bunny_channel }
|
|
13
|
+
|
|
14
|
+
describe '#new' do
|
|
15
|
+
before do
|
|
16
|
+
EventRouting do
|
|
17
|
+
accept_from('rabbit_feed') do
|
|
18
|
+
event('test') {|event|}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'binds the queue to the exchange' do
|
|
24
|
+
expect(bunny_queue).to receive(:bind).with('rabbit_feed_exchange', { routing_key: 'test.rabbit_feed.test'})
|
|
25
|
+
subject
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'assigns the queue' do
|
|
29
|
+
expect(subject.queue).to eq bunny_queue
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'preserves message order' do
|
|
33
|
+
expect(bunny_channel).to receive(:prefetch).with(1)
|
|
34
|
+
subject
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe '#connection_options' do
|
|
39
|
+
|
|
40
|
+
it 'uses a threaded connection' do
|
|
41
|
+
expect(described_class.connection_options).to include(threaded: true)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe '#consume' do
|
|
46
|
+
before do
|
|
47
|
+
allow(bunny_queue).to receive(:subscribe).and_yield(double(:delivery_info, delivery_tag: :tag), 'properties', 'payload')
|
|
48
|
+
allow_any_instance_of(described_class).to receive(:sleep)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'yields the payload' do
|
|
52
|
+
subject.consume { |payload| payload.should eq 'payload'}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'acknowledges the message' do
|
|
56
|
+
expect(bunny_channel).to receive(:ack)
|
|
57
|
+
subject.consume { }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'when an exception is raised' do
|
|
61
|
+
|
|
62
|
+
context 'when Airbrake is defined' do
|
|
63
|
+
before do
|
|
64
|
+
stub_const('Airbrake', double(:airbrake, configuration: airbrake_configuration))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context 'and the Airbrake configuration is public' do
|
|
68
|
+
let(:airbrake_configuration) { double(:airbrake_configuration, public?: true) }
|
|
69
|
+
|
|
70
|
+
it 'notifies airbrake' do
|
|
71
|
+
expect(Airbrake).to receive(:notify_or_ignore).with(an_instance_of RuntimeError)
|
|
72
|
+
|
|
73
|
+
expect{ subject.consume { raise 'Consuming time' } }.not_to raise_error
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'negatively acknowledges the message' do
|
|
79
|
+
expect(bunny_channel).to receive(:nack)
|
|
80
|
+
subject.consume { raise 'Consuming time' }
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|