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.
@@ -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