right_amqp 0.3.1 → 0.3.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.
- data/lib/right_amqp/amqp/client.rb +59 -18
- data/right_amqp.gemspec +2 -2
- data/spec/amqp/client_extensions_spec.rb +255 -0
- data/spec/spec_helper.rb +2 -1
- metadata +14 -39
- data/spec/amqp/client_reconnect_spec.rb +0 -105
@@ -6,6 +6,7 @@ module AMQP
|
|
6
6
|
|
7
7
|
module BasicClient
|
8
8
|
def process_frame frame
|
9
|
+
@last_data_received = Time.now
|
9
10
|
if mq = channels[frame.channel]
|
10
11
|
mq.process_frame(frame)
|
11
12
|
return
|
@@ -48,8 +49,7 @@ module AMQP
|
|
48
49
|
|
49
50
|
when Frame::Heartbeat
|
50
51
|
logger.debug("[amqp] Received heartbeat from broker #{@settings[:identity]}")
|
51
|
-
@
|
52
|
-
|
52
|
+
@last_heartbeat_received = @last_data_received
|
53
53
|
end
|
54
54
|
|
55
55
|
# Make callback now that handshake with the broker has completed
|
@@ -111,21 +111,48 @@ module AMQP
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def init_heartbeat
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
114
|
+
# Randomly offset start of heartbeat timer to help separate heartbeat
|
115
|
+
# activity when there are multiple broker connections active
|
116
|
+
EM.add_timer(rand(@settings[:heartbeat])) do
|
117
|
+
begin
|
118
|
+
# While connected, a heartbeat or some other data is expected to be received from
|
119
|
+
# the broker at least every 2 x :heartbeat seconds, otherwise the connection is
|
120
|
+
# assumed to be broken and therefore is closed to cause an automatic reconnect.
|
121
|
+
# While connected, this client will send a heartbeat every :heartbeat
|
122
|
+
# seconds regardless of any other send activity. The RabbitMQ broker will behave
|
123
|
+
# similarly and drop the connection if it does not receive a heartbeat or other
|
124
|
+
# data in time.
|
125
|
+
logger.info("[amqp] Initializing heartbeat for broker #{@settings[:identity]} to #{@settings[:heartbeat]} sec")
|
126
|
+
|
127
|
+
timeout_factor = 2
|
128
|
+
@heartbeat_timer.cancel if @heartbeat_timer
|
129
|
+
@heartbeat_timer = EM::PeriodicTimer.new(@settings[:heartbeat]) do
|
130
|
+
begin
|
131
|
+
if connected?
|
132
|
+
now = Time.now
|
133
|
+
if @last_data_received < (now - (@settings[:heartbeat] * timeout_factor))
|
134
|
+
data_received = (now - @last_data_received).to_i if @last_data_received
|
135
|
+
heartbeat_received = (now - @last_heartbeat_received).to_i if @last_heartbeat_received
|
136
|
+
heartbeat_sent = (now - @last_heartbeat_sent).to_i if @last_heartbeat_sent
|
137
|
+
logger.info("[amqp] Reconnecting to broker #{@settings[:identity]} due to heartbeat timeout: " +
|
138
|
+
"last data received #{data_received.inspect} sec ago, " +
|
139
|
+
"last heartbeat received #{heartbeat_received.inspect} sec ago, " +
|
140
|
+
"last heartbeat sent #{heartbeat_sent.inspect} sec ago")
|
141
|
+
close_connection # which results in an unbind and an automatic reconnect
|
142
|
+
else
|
143
|
+
logger.debug("[amqp] Sending heartbeat to broker #{@settings[:identity]}")
|
144
|
+
send AMQP::Frame::Heartbeat.new, :channel => 0
|
145
|
+
@last_heartbeat_sent = Time.now
|
146
|
+
end
|
147
|
+
else
|
148
|
+
logger.debug("[amqp] Skipping heartbeat check for broker #{@settings[:identity]} because disconnected")
|
149
|
+
end
|
150
|
+
rescue Exception => e
|
151
|
+
logger.error("[amqp] Failed heartbeat check (#{e})\n" + e.backtrace.join("\n"))
|
152
|
+
end
|
128
153
|
end
|
154
|
+
rescue Exception => e
|
155
|
+
logger.error("[amqp] Failed heartbeat initialization (#{e})\n" + e.backtrace.join("\n"))
|
129
156
|
end
|
130
157
|
end
|
131
158
|
end
|
@@ -193,6 +220,8 @@ module AMQP
|
|
193
220
|
#:startdoc:
|
194
221
|
|
195
222
|
def close &on_disconnect
|
223
|
+
@heartbeat_timer.cancel if @heartbeat_timer
|
224
|
+
@heartbeat_timer = nil
|
196
225
|
if on_disconnect
|
197
226
|
@closing = true
|
198
227
|
@on_disconnect = proc{
|
@@ -218,7 +247,13 @@ module AMQP
|
|
218
247
|
def reconnect force = false
|
219
248
|
if @reconnecting and not force
|
220
249
|
# Wait after first reconnect attempt and in between each subsequent attempt
|
221
|
-
EM.add_timer(@settings[:reconnect_interval] || 5)
|
250
|
+
EM.add_timer(@settings[:reconnect_interval] || 5) do
|
251
|
+
begin
|
252
|
+
reconnect(true)
|
253
|
+
rescue Exception => e
|
254
|
+
logger.exception("[amqp] Failed to reconnect", e, :trace)
|
255
|
+
end
|
256
|
+
end
|
222
257
|
return
|
223
258
|
end
|
224
259
|
|
@@ -236,7 +271,13 @@ module AMQP
|
|
236
271
|
again = again.call if again.is_a?(Proc)
|
237
272
|
if again.is_a?(Numeric)
|
238
273
|
# Wait before making initial reconnect attempt
|
239
|
-
EM.add_timer(again)
|
274
|
+
EM.add_timer(again) do
|
275
|
+
begin
|
276
|
+
reconnect(true)
|
277
|
+
rescue Exception => e
|
278
|
+
logger.exception("[amqp] Failed to reconnect", e, :trace)
|
279
|
+
end
|
280
|
+
end
|
240
281
|
return
|
241
282
|
elsif ![nil, true].include?(again)
|
242
283
|
raise ::AMQP::Error, "Could not interpret :reconnect_delay => #{again.inspect}; expected nil, true, or Numeric"
|
data/right_amqp.gemspec
CHANGED
@@ -24,8 +24,8 @@ require 'rubygems'
|
|
24
24
|
|
25
25
|
Gem::Specification.new do |spec|
|
26
26
|
spec.name = 'right_amqp'
|
27
|
-
spec.version = '0.3.
|
28
|
-
spec.date = '2012-
|
27
|
+
spec.version = '0.3.2'
|
28
|
+
spec.date = '2012-10-04'
|
29
29
|
spec.authors = ['Lee Kirchhoff']
|
30
30
|
spec.email = 'lee@rightscale.com'
|
31
31
|
spec.homepage = 'https://github.com/rightscale/right_amqp'
|
@@ -0,0 +1,255 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2012 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
24
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'right_amqp'))
|
25
|
+
|
26
|
+
describe AMQP::Client do
|
27
|
+
|
28
|
+
include RightAMQP::SpecHelper
|
29
|
+
include FlexMock::ArgumentTypes
|
30
|
+
|
31
|
+
context 'reconnect' do
|
32
|
+
|
33
|
+
class SUT
|
34
|
+
include AMQP::Client
|
35
|
+
|
36
|
+
attr_accessor :reconnecting, :settings, :channels
|
37
|
+
end
|
38
|
+
|
39
|
+
before(:each) do
|
40
|
+
setup_logger
|
41
|
+
@sut = flexmock(SUT.new)
|
42
|
+
@sut.reconnecting = false
|
43
|
+
@sut.settings = {:host => 'testhost', :port=>'12345'}
|
44
|
+
@sut.channels = {}
|
45
|
+
|
46
|
+
@sut.should_receive(:initialize)
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with no :reconnect_delay' do
|
50
|
+
it 'should reconnect immediately' do
|
51
|
+
flexmock(EM).should_receive(:reconnect).once
|
52
|
+
flexmock(EM).should_receive(:add_timer).never
|
53
|
+
|
54
|
+
@sut.reconnect()
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with a :reconnect_delay of true' do
|
59
|
+
it 'should reconnect immediately' do
|
60
|
+
@sut.settings[:reconnect_delay] = true
|
61
|
+
|
62
|
+
flexmock(EM).should_receive(:reconnect).once
|
63
|
+
flexmock(EM).should_receive(:add_timer).never
|
64
|
+
|
65
|
+
@sut.reconnect()
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with a :reconnect_delay of 15 seconds' do
|
70
|
+
it 'should schedule a reconnect attempt in 15s' do
|
71
|
+
@sut.settings[:reconnect_delay] = 15
|
72
|
+
|
73
|
+
flexmock(EM).should_receive(:reconnect).never
|
74
|
+
flexmock(EM).should_receive(:add_timer).with(15, Proc).once
|
75
|
+
|
76
|
+
@sut.reconnect()
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with a :reconnect_delay containing a Proc that returns 30' do
|
81
|
+
it 'should schedule a reconnect attempt in 30s' do
|
82
|
+
@sut.settings[:reconnect_delay] = Proc.new {30}
|
83
|
+
|
84
|
+
flexmock(EM).should_receive(:reconnect).never
|
85
|
+
flexmock(EM).should_receive(:add_timer).with(30, Proc).once
|
86
|
+
|
87
|
+
@sut.reconnect()
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'with a :reconnect_interval of 5 seconds' do
|
92
|
+
it 'should schedule reconnect attempts on a 5s interval' do
|
93
|
+
@sut.reconnecting = true
|
94
|
+
@sut.settings[:reconnect_delay] = 15
|
95
|
+
@sut.settings[:reconnect_interval] = 5
|
96
|
+
|
97
|
+
flexmock(EM).should_receive(:reconnect).never
|
98
|
+
flexmock(EM).should_receive(:add_timer).with(5, Proc).once
|
99
|
+
|
100
|
+
@sut.reconnect()
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
context "heartbeat" do
|
107
|
+
|
108
|
+
class SUT
|
109
|
+
include AMQP::Client
|
110
|
+
|
111
|
+
attr_accessor :connected, :reconnecting, :settings, :channels, :heartbeat_timer
|
112
|
+
attr_accessor :last_data_received, :last_heartbeat_received, :last_heartbeat_sent
|
113
|
+
end
|
114
|
+
|
115
|
+
before(:each) do
|
116
|
+
setup_logger
|
117
|
+
@sut = flexmock(SUT.new)
|
118
|
+
@sut.reconnecting = false
|
119
|
+
@sut.channels = {}
|
120
|
+
@sut.should_receive(:initialize)
|
121
|
+
@sut.should_receive(:send_data)
|
122
|
+
|
123
|
+
@tune_payload = flexmock("tune payload", :class => AMQP::Protocol::Connection::Tune)
|
124
|
+
@method_frame = flexmock("method frame", :class => AMQP::Frame::Method, :channel => 0, :payload => @tune_payload)
|
125
|
+
@heartbeat_frame = flexmock("heartbeat frame", :class => AMQP::Frame::Heartbeat, :channel => 0)
|
126
|
+
end
|
127
|
+
|
128
|
+
context "with no :heartbeat setting" do
|
129
|
+
it "should never initialize heartbeat" do
|
130
|
+
@sut.should_receive(:init_heartbeat).never
|
131
|
+
@sut.connection_completed
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should send :heartbeat setting of 0 to broker" do
|
135
|
+
flexmock(AMQP::Protocol::Connection::TuneOk).should_receive(:new).with(hsh(:heartbeat => 0))
|
136
|
+
@sut.process_frame(@method_frame)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "with a :heartbeat setting of 0" do
|
141
|
+
before(:each) do
|
142
|
+
@sut.settings = {:heartbeat => 0}
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should never initialize heartbeat" do
|
146
|
+
@sut.should_receive(:init_heartbeat).never
|
147
|
+
@sut.connection_completed
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should send :heartbeat setting of 0 to broker" do
|
151
|
+
flexmock(AMQP::Protocol::Connection::TuneOk).should_receive(:new).with(hsh(:heartbeat => 0))
|
152
|
+
@sut.process_frame(@method_frame)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "with a :heartbeat setting > 0" do
|
157
|
+
|
158
|
+
before(:each) do
|
159
|
+
@now = Time.at(1000000)
|
160
|
+
flexmock(Time).should_receive(:now).and_return(@now).by_default
|
161
|
+
@periodic_timer = flexmock("periodic timer")
|
162
|
+
flexmock(EM::PeriodicTimer).should_receive(:new).and_return(@periodic_timer).and_yield.by_default
|
163
|
+
flexmock(EM::PeriodicTimer).should_receive(:cancel).by_default
|
164
|
+
flexmock(EM).should_receive(:add_timer).and_yield.by_default
|
165
|
+
|
166
|
+
@heartbeat = 30
|
167
|
+
@sut.settings = {:heartbeat => @heartbeat, :identity => "test-heartbeat"}
|
168
|
+
@sut.connected = true
|
169
|
+
@sut.last_data_received = @now
|
170
|
+
@sut.last_heartbeat_received = nil
|
171
|
+
@sut.last_heartbeat_sent = nil
|
172
|
+
end
|
173
|
+
|
174
|
+
context "and opened connection is being tuned" do
|
175
|
+
it "should send :heartbeat setting to broker" do
|
176
|
+
flexmock(AMQP::Protocol::Connection::TuneOk).should_receive(:new).with(hsh(:heartbeat => @heartbeat))
|
177
|
+
@sut.process_frame(@method_frame)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context "and connection has completed" do
|
182
|
+
it "should initialize heartbeat" do
|
183
|
+
@sut.should_receive(:init_heartbeat).once
|
184
|
+
@sut.connection_completed
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should initialize timer to start at a random :heartbeat time" do
|
188
|
+
flexmock(EM).should_receive(:add_timer).with(on { |arg| arg >= 0 && arg < @heartbeat }, Proc).once
|
189
|
+
@sut.connection_completed
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "and the heartbeat timer initialization fails" do
|
194
|
+
it "should log exception" do
|
195
|
+
@logger.should_receive(:info).with(/Initializing heartbeat for broker/).once
|
196
|
+
@logger.should_receive(:error).with(/Failed heartbeat initialization/).once
|
197
|
+
flexmock(EM::PeriodicTimer).should_receive(:new).and_raise(Exception)
|
198
|
+
@sut.init_heartbeat
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "and the timer fires when not connected" do
|
203
|
+
it "should log a debug message but not perform check" do
|
204
|
+
@logger.should_receive(:debug).with(/Skipping heartbeat check for broker/).once
|
205
|
+
flexmock(EM::PeriodicTimer).should_receive(:new).and_yield
|
206
|
+
@sut.connected = false
|
207
|
+
@sut.init_heartbeat
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context "and the timer fires when connected" do
|
212
|
+
|
213
|
+
context "and no data has been received in 2 x :heartbeat interval" do
|
214
|
+
it "should close connection to force reconnect" do
|
215
|
+
@sut.last_data_received = @now - (@heartbeat * 2) - 1
|
216
|
+
@logger.should_receive(:info).with(/Initializing heartbeat for broker/).once
|
217
|
+
@logger.should_receive(:info).with(/Reconnecting to broker/).once
|
218
|
+
@sut.should_receive(:close_connection).once
|
219
|
+
@sut.init_heartbeat
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context "and timeout check passes" do
|
224
|
+
it "should send heartbeat" do
|
225
|
+
@logger.should_receive(:debug).with(/Sending heartbeat to broker/).once
|
226
|
+
@sut.should_receive(:send).with(AMQP::Frame::Heartbeat, :channel => 0).once
|
227
|
+
@sut.init_heartbeat
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context "and the heartbeat check fails" do
|
232
|
+
it "should log exception" do
|
233
|
+
@logger.should_receive(:error).with(/Failed heartbeat check/).once
|
234
|
+
@sut.should_receive(:send).and_raise(Exception)
|
235
|
+
@sut.init_heartbeat
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
context "and connection is being closed" do
|
242
|
+
it "should cancel heartbeat timer" do
|
243
|
+
@periodic_timer.should_receive(:cancel).once
|
244
|
+
@sut.connection_completed
|
245
|
+
@sut.heartbeat_timer.should_not be_nil
|
246
|
+
@sut.close
|
247
|
+
@sut.heartbeat_timer.should be_nil
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -44,6 +44,7 @@ module RightAMQP
|
|
44
44
|
def setup_logger
|
45
45
|
@logger = flexmock("logger")
|
46
46
|
@logger.should_receive(:level).and_return(:info).by_default
|
47
|
+
@logger.should_receive(:exception).by_default.and_return { |m| raise m }
|
47
48
|
@logger.should_receive(:error).by_default.and_return { |m| raise m }
|
48
49
|
@logger.should_receive(:warning).by_default.and_return { |m| raise m }
|
49
50
|
@logger.should_receive(:info).by_default
|
@@ -53,4 +54,4 @@ module RightAMQP
|
|
53
54
|
|
54
55
|
end
|
55
56
|
|
56
|
-
end
|
57
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: right_amqp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 3
|
9
|
-
- 1
|
10
|
-
version: 0.3.1
|
4
|
+
prerelease:
|
5
|
+
version: 0.3.2
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Lee Kirchhoff
|
@@ -15,47 +10,33 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2012-
|
19
|
-
default_executable:
|
13
|
+
date: 2012-10-04 00:00:00 Z
|
20
14
|
dependencies:
|
21
15
|
- !ruby/object:Gem::Dependency
|
22
|
-
|
16
|
+
name: right_support
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
18
|
none: false
|
24
19
|
requirements:
|
25
20
|
- - ">="
|
26
21
|
- !ruby/object:Gem::Version
|
27
|
-
hash: 11
|
28
|
-
segments:
|
29
|
-
- 1
|
30
|
-
- 2
|
31
22
|
version: "1.2"
|
32
23
|
- - <
|
33
24
|
- !ruby/object:Gem::Version
|
34
|
-
hash: 7
|
35
|
-
segments:
|
36
|
-
- 3
|
37
|
-
- 0
|
38
25
|
version: "3.0"
|
39
|
-
requirement: *id001
|
40
|
-
name: right_support
|
41
|
-
prerelease: false
|
42
26
|
type: :runtime
|
27
|
+
prerelease: false
|
28
|
+
version_requirements: *id001
|
43
29
|
- !ruby/object:Gem::Dependency
|
44
|
-
|
30
|
+
name: eventmachine
|
31
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
45
32
|
none: false
|
46
33
|
requirements:
|
47
34
|
- - ~>
|
48
35
|
- !ruby/object:Gem::Version
|
49
|
-
hash: 59
|
50
|
-
segments:
|
51
|
-
- 0
|
52
|
-
- 12
|
53
|
-
- 10
|
54
36
|
version: 0.12.10
|
55
|
-
requirement: *id002
|
56
|
-
name: eventmachine
|
57
|
-
prerelease: false
|
58
37
|
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: *id002
|
59
40
|
description: |
|
60
41
|
RightAMQP provides a high availability client for interfacing with the
|
61
42
|
RightScale RabbitMQ broker using the AMQP protocol. The AMQP version on which
|
@@ -100,12 +81,11 @@ files:
|
|
100
81
|
- lib/right_amqp/mq/queue.rb
|
101
82
|
- lib/right_amqp/mq/rpc.rb
|
102
83
|
- right_amqp.gemspec
|
103
|
-
- spec/amqp/
|
84
|
+
- spec/amqp/client_extensions_spec.rb
|
104
85
|
- spec/ha_client/broker_client_spec.rb
|
105
86
|
- spec/ha_client/ha_broker_client_spec.rb
|
106
87
|
- spec/spec.opts
|
107
88
|
- spec/spec_helper.rb
|
108
|
-
has_rdoc: true
|
109
89
|
homepage: https://github.com/rightscale/right_amqp
|
110
90
|
licenses: []
|
111
91
|
|
@@ -122,25 +102,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
102
|
requirements:
|
123
103
|
- - ">="
|
124
104
|
- !ruby/object:Gem::Version
|
125
|
-
hash: 57
|
126
|
-
segments:
|
127
|
-
- 1
|
128
|
-
- 8
|
129
|
-
- 7
|
130
105
|
version: 1.8.7
|
131
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
107
|
none: false
|
133
108
|
requirements:
|
134
109
|
- - ">="
|
135
110
|
- !ruby/object:Gem::Version
|
136
|
-
hash:
|
111
|
+
hash: 60400910479135744
|
137
112
|
segments:
|
138
113
|
- 0
|
139
114
|
version: "0"
|
140
115
|
requirements: []
|
141
116
|
|
142
117
|
rubyforge_project:
|
143
|
-
rubygems_version: 1.
|
118
|
+
rubygems_version: 1.8.11
|
144
119
|
signing_key:
|
145
120
|
specification_version: 3
|
146
121
|
summary: Client for interfacing to RightScale RabbitMQ broker using AMQP
|
@@ -1,105 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2009-2012 RightScale Inc
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
-
# a copy of this software and associated documentation files (the
|
6
|
-
# "Software"), to deal in the Software without restriction, including
|
7
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
-
# the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be
|
13
|
-
# included in all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
-
|
23
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
24
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'right_amqp'))
|
25
|
-
|
26
|
-
describe AMQP::Client do
|
27
|
-
|
28
|
-
context 'with an incorrect AMQP password' do
|
29
|
-
|
30
|
-
include RightAMQP::SpecHelper
|
31
|
-
|
32
|
-
class SUT
|
33
|
-
include AMQP::Client
|
34
|
-
|
35
|
-
attr_accessor :reconnecting, :settings, :channels
|
36
|
-
end
|
37
|
-
|
38
|
-
before(:each) do
|
39
|
-
setup_logger
|
40
|
-
@sut = flexmock(SUT.new)
|
41
|
-
@sut.reconnecting = false
|
42
|
-
@sut.settings = {:host => 'testhost', :port=>'12345'}
|
43
|
-
@sut.channels = {}
|
44
|
-
|
45
|
-
@sut.should_receive(:initialize)
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'and no :reconnect_delay' do
|
49
|
-
it 'should reconnect immediately' do
|
50
|
-
flexmock(EM).should_receive(:reconnect).once
|
51
|
-
flexmock(EM).should_receive(:add_timer).never
|
52
|
-
|
53
|
-
@sut.reconnect()
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'and a :reconnect_delay of true' do
|
58
|
-
it 'should reconnect immediately' do
|
59
|
-
@sut.settings[:reconnect_delay] = true
|
60
|
-
|
61
|
-
flexmock(EM).should_receive(:reconnect).once
|
62
|
-
flexmock(EM).should_receive(:add_timer).never
|
63
|
-
|
64
|
-
@sut.reconnect()
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context 'and a :reconnect_delay of 15 seconds' do
|
69
|
-
it 'should schedule a reconnect attempt in 15s' do
|
70
|
-
@sut.settings[:reconnect_delay] = 15
|
71
|
-
|
72
|
-
flexmock(EM).should_receive(:reconnect).never
|
73
|
-
flexmock(EM).should_receive(:add_timer).with(15, Proc).once
|
74
|
-
|
75
|
-
@sut.reconnect()
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'and a :reconnect_delay containing a Proc that returns 30' do
|
80
|
-
it 'should schedule a reconnect attempt in 30s' do
|
81
|
-
@sut.settings[:reconnect_delay] = Proc.new {30}
|
82
|
-
|
83
|
-
flexmock(EM).should_receive(:reconnect).never
|
84
|
-
flexmock(EM).should_receive(:add_timer).with(30, Proc).once
|
85
|
-
|
86
|
-
@sut.reconnect()
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context 'and a :reconnect_interval of 5 seconds' do
|
91
|
-
it 'should schedule reconnect attempts on a 5s interval' do
|
92
|
-
@sut.reconnecting = true
|
93
|
-
@sut.settings[:reconnect_delay] = 15
|
94
|
-
@sut.settings[:reconnect_interval] = 5
|
95
|
-
|
96
|
-
flexmock(EM).should_receive(:reconnect).never
|
97
|
-
flexmock(EM).should_receive(:add_timer).with(5, Proc).once
|
98
|
-
|
99
|
-
@sut.reconnect()
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|