right_amqp 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- @last_server_heartbeat = Time.now
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
- logger.debug("[amqp] Initializing heartbeat for broker #{@settings[:identity]} to #{@settings[:heartbeat]}")
115
- @last_server_heartbeat = Time.now
116
-
117
- @timer.cancel if @timer
118
- @timer = EM::PeriodicTimer.new(@settings[:heartbeat]) do
119
- if connected?
120
- if @last_server_heartbeat < (Time.now - (@settings[:heartbeat] * 2))
121
- log "Reconnecting due to missing server heartbeats"
122
- logger.info("[amqp] Reconnecting to broker #{@settings[:identity]} due to missing server heartbeats")
123
- reconnect(true)
124
- else
125
- logger.debug("[amqp] Sending heartbeat to broker #{@settings[:identity]}")
126
- @last_server_heartbeat = Time.now
127
- send AMQP::Frame::Heartbeat.new, :channel => 0
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) { reconnect(true) }
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) { reconnect(true) }
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.1'
28
- spec.date = '2012-06-08'
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
- hash: 17
5
- prerelease: false
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-06-08 00:00:00 -07:00
19
- default_executable:
13
+ date: 2012-10-04 00:00:00 Z
20
14
  dependencies:
21
15
  - !ruby/object:Gem::Dependency
22
- version_requirements: &id001 !ruby/object:Gem::Requirement
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
- version_requirements: &id002 !ruby/object:Gem::Requirement
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/client_reconnect_spec.rb
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: 3
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.3.7
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