onstomp 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +3 -0
- data/Gemfile +1 -0
- data/extra_doc/API.md +19 -19
- data/extra_doc/API.md.erb +1 -1
- data/lib/onstomp/components/frame.rb +6 -6
- data/lib/onstomp/components/uri.rb +1 -1
- data/lib/onstomp/connections/base.rb +38 -33
- data/lib/onstomp/connections/serializers/stomp_1.rb +1 -1
- data/lib/onstomp/connections/serializers/stomp_1_1.rb +2 -2
- data/lib/onstomp/failover/client.rb +38 -33
- data/lib/onstomp/failover/failover_configurable.rb +2 -2
- data/lib/onstomp/failover/failover_events.rb +7 -2
- data/lib/onstomp/failover/uri.rb +5 -5
- data/lib/onstomp/failover.rb +1 -1
- data/lib/onstomp/interfaces/client_events.rb +4 -4
- data/lib/onstomp/interfaces/connection_events.rb +4 -4
- data/lib/onstomp/interfaces/frame_methods.rb +13 -4
- data/lib/onstomp/version.rb +1 -1
- data/onstomp.gemspec +1 -1
- data/spec/onstomp/full_stacks/failover_spec.rb +2 -2
- data/spec/onstomp/full_stacks/open-uri_spec.rb +3 -3
- data/spec/support/frame_matchers.rb +0 -1
- metadata +4 -5
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/extra_doc/API.md
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
<tr>
|
18
18
|
<td>{OnStomp::Interfaces::FrameMethods#abort abort}</td>
|
19
19
|
<td>
|
20
|
-
<code>abort(tx_id, headers
|
20
|
+
<code>abort(tx_id, headers=<optional hash>)</code>
|
21
21
|
</td>
|
22
22
|
<td style="background-color: #bfb;">true</td>
|
23
23
|
<td style="background-color: #bfb;">true</td>
|
@@ -25,7 +25,7 @@
|
|
25
25
|
<tr>
|
26
26
|
<td>{OnStomp::Interfaces::FrameMethods#ack ack}</td>
|
27
27
|
<td>
|
28
|
-
<code>ack(message_frame, headers
|
28
|
+
<code>ack(message_frame, headers=<optional hash>)</code>
|
29
29
|
</td>
|
30
30
|
<td style="background-color: #bfb;">true</td>
|
31
31
|
<td style="background-color: #bfb;">true</td>
|
@@ -33,7 +33,7 @@
|
|
33
33
|
<tr>
|
34
34
|
<td>{OnStomp::Interfaces::FrameMethods#ack ack}</td>
|
35
35
|
<td>
|
36
|
-
<code>ack(message_id, headers
|
36
|
+
<code>ack(message_id, headers=<optional hash>)</code>
|
37
37
|
</td>
|
38
38
|
<td style="background-color: #bfb;">true</td>
|
39
39
|
<td style="background-color: #fbb;">false</td>
|
@@ -41,7 +41,7 @@
|
|
41
41
|
<tr>
|
42
42
|
<td>{OnStomp::Interfaces::FrameMethods#ack ack}</td>
|
43
43
|
<td>
|
44
|
-
<code>ack(message_id, subscription_id, headers
|
44
|
+
<code>ack(message_id, subscription_id, headers=<optional hash>)</code>
|
45
45
|
</td>
|
46
46
|
<td style="background-color: #bfb;">true</td>
|
47
47
|
<td style="background-color: #bfb;">true</td>
|
@@ -201,7 +201,7 @@
|
|
201
201
|
<tr>
|
202
202
|
<td>{OnStomp::Interfaces::FrameMethods#begin begin}</td>
|
203
203
|
<td>
|
204
|
-
<code>begin(tx_id, headers
|
204
|
+
<code>begin(tx_id, headers=<optional hash>)</code>
|
205
205
|
</td>
|
206
206
|
<td style="background-color: #bfb;">true</td>
|
207
207
|
<td style="background-color: #bfb;">true</td>
|
@@ -217,7 +217,7 @@
|
|
217
217
|
<tr>
|
218
218
|
<td>{OnStomp::Interfaces::FrameMethods#commit commit}</td>
|
219
219
|
<td>
|
220
|
-
<code>commit(tx_id, headers
|
220
|
+
<code>commit(tx_id, headers=<optional hash>)</code>
|
221
221
|
</td>
|
222
222
|
<td style="background-color: #bfb;">true</td>
|
223
223
|
<td style="background-color: #bfb;">true</td>
|
@@ -225,7 +225,7 @@
|
|
225
225
|
<tr>
|
226
226
|
<td>{OnStomp::Client#connect connect}</td>
|
227
227
|
<td>
|
228
|
-
<code>connect(headers
|
228
|
+
<code>connect(headers=<optional hash>)</code>
|
229
229
|
</td>
|
230
230
|
<td style="background-color: #bfb;">true</td>
|
231
231
|
<td style="background-color: #bfb;">true</td>
|
@@ -241,7 +241,7 @@
|
|
241
241
|
<tr>
|
242
242
|
<td>{OnStomp::Client#disconnect disconnect}</td>
|
243
243
|
<td>
|
244
|
-
<code>disconnect_with_flush(headers
|
244
|
+
<code>disconnect_with_flush(headers=<optional hash>)</code>
|
245
245
|
</td>
|
246
246
|
<td style="background-color: #bfb;">true</td>
|
247
247
|
<td style="background-color: #bfb;">true</td>
|
@@ -249,7 +249,7 @@
|
|
249
249
|
<tr>
|
250
250
|
<td>{OnStomp::Interfaces::FrameMethods#disconnect disconnect}</td>
|
251
251
|
<td>
|
252
|
-
<code>disconnect(headers
|
252
|
+
<code>disconnect(headers=<optional hash>)</code>
|
253
253
|
</td>
|
254
254
|
<td style="background-color: #bfb;">true</td>
|
255
255
|
<td style="background-color: #bfb;">true</td>
|
@@ -257,7 +257,7 @@
|
|
257
257
|
<tr>
|
258
258
|
<td>{OnStomp::Client#disconnect_with_flush disconnect_with_flush}</td>
|
259
259
|
<td>
|
260
|
-
<code>disconnect_with_flush(headers
|
260
|
+
<code>disconnect_with_flush(headers=<optional hash>)</code>
|
261
261
|
</td>
|
262
262
|
<td style="background-color: #bfb;">true</td>
|
263
263
|
<td style="background-color: #bfb;">true</td>
|
@@ -265,7 +265,7 @@
|
|
265
265
|
<tr>
|
266
266
|
<td>{OnStomp::Client#initialize initialize}</td>
|
267
267
|
<td>
|
268
|
-
<code>initialize(uri, options
|
268
|
+
<code>initialize(uri, options=<optional hash>)</code>
|
269
269
|
</td>
|
270
270
|
<td style="background-color: #bfb;">true</td>
|
271
271
|
<td style="background-color: #bfb;">true</td>
|
@@ -273,7 +273,7 @@
|
|
273
273
|
<tr>
|
274
274
|
<td>{OnStomp::Interfaces::FrameMethods#nack nack}</td>
|
275
275
|
<td>
|
276
|
-
<code>nack(message_id, subscription_id, heders
|
276
|
+
<code>nack(message_id, subscription_id, heders=<optional hash>)</code>
|
277
277
|
</td>
|
278
278
|
<td style="background-color: #fbb;">false</td>
|
279
279
|
<td style="background-color: #bfb;">true</td>
|
@@ -281,7 +281,7 @@
|
|
281
281
|
<tr>
|
282
282
|
<td>{OnStomp::Interfaces::FrameMethods#nack nack}</td>
|
283
283
|
<td>
|
284
|
-
<code>nack(message_frame, headers
|
284
|
+
<code>nack(message_frame, headers=<optional hash>)</code>
|
285
285
|
</td>
|
286
286
|
<td style="background-color: #fbb;">false</td>
|
287
287
|
<td style="background-color: #bfb;">true</td>
|
@@ -441,7 +441,7 @@
|
|
441
441
|
<tr>
|
442
442
|
<td>{OnStomp::Client#open open}</td>
|
443
443
|
<td>
|
444
|
-
<code>connect(headers
|
444
|
+
<code>connect(headers=<optional hash>)</code>
|
445
445
|
</td>
|
446
446
|
<td style="background-color: #bfb;">true</td>
|
447
447
|
<td style="background-color: #bfb;">true</td>
|
@@ -449,7 +449,7 @@
|
|
449
449
|
<tr>
|
450
450
|
<td>{OnStomp::Interfaces::FrameMethods#puts puts}</td>
|
451
451
|
<td>
|
452
|
-
<code>send(dest, body, headers
|
452
|
+
<code>send(dest, body, headers=<optional hash>, &cb)</code>
|
453
453
|
</td>
|
454
454
|
<td style="background-color: #bfb;">true</td>
|
455
455
|
<td style="background-color: #bfb;">true</td>
|
@@ -457,7 +457,7 @@
|
|
457
457
|
<tr>
|
458
458
|
<td>{OnStomp::Interfaces::FrameMethods#send send}</td>
|
459
459
|
<td>
|
460
|
-
<code>send(dest, body, headers
|
460
|
+
<code>send(dest, body, headers=<optional hash>, &cb)</code>
|
461
461
|
</td>
|
462
462
|
<td style="background-color: #bfb;">true</td>
|
463
463
|
<td style="background-color: #bfb;">true</td>
|
@@ -465,7 +465,7 @@
|
|
465
465
|
<tr>
|
466
466
|
<td>{OnStomp::Interfaces::FrameMethods#subscribe subscribe}</td>
|
467
467
|
<td>
|
468
|
-
<code>subscribe(dest, headers
|
468
|
+
<code>subscribe(dest, headers=<optional hash>, &cb)</code>
|
469
469
|
</td>
|
470
470
|
<td style="background-color: #bfb;">true</td>
|
471
471
|
<td style="background-color: #bfb;">true</td>
|
@@ -473,7 +473,7 @@
|
|
473
473
|
<tr>
|
474
474
|
<td>{OnStomp::Interfaces::FrameMethods#unsubscribe unsubscribe}</td>
|
475
475
|
<td>
|
476
|
-
<code>unsubscribe(id, headers
|
476
|
+
<code>unsubscribe(id, headers=<optional hash>)</code>
|
477
477
|
</td>
|
478
478
|
<td style="background-color: #bfb;">true</td>
|
479
479
|
<td style="background-color: #bfb;">true</td>
|
@@ -481,7 +481,7 @@
|
|
481
481
|
<tr>
|
482
482
|
<td>{OnStomp::Interfaces::FrameMethods#unsubscribe unsubscribe}</td>
|
483
483
|
<td>
|
484
|
-
<code>unsubscribe(subscribe_frame, headers
|
484
|
+
<code>unsubscribe(subscribe_frame, headers=<optional hash>)</code>
|
485
485
|
</td>
|
486
486
|
<td style="background-color: #bfb;">true</td>
|
487
487
|
<td style="background-color: #bfb;">true</td>
|
data/extra_doc/API.md.erb
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
<tr>
|
21
21
|
<td>{<%= meth[:yard_link] %> <%= meth[:name]%>}</td>
|
22
22
|
<td>
|
23
|
-
<code><%= meth[:signature] %></code>
|
23
|
+
<code><%= meth[:signature].gsub('{}', '<optional hash>') %></code>
|
24
24
|
</td>
|
25
25
|
<% meth[:protocols].each do |proto| %>
|
26
26
|
<td style="background-color: #<%= proto ? 'bfb' : 'fbb' %>;"><%= proto %></td>
|
@@ -43,16 +43,16 @@ class OnStomp::Components::Frame
|
|
43
43
|
# frame['other header'] = 42 #=> '42'
|
44
44
|
def []=(name, val); @headers[name] = val; end
|
45
45
|
|
46
|
-
# If a
|
46
|
+
# If a `content-length` header is set, returns it after converting it to
|
47
47
|
# an integer.
|
48
48
|
# @return [Fixnum, nil]
|
49
49
|
def content_length
|
50
50
|
header?(:'content-length') ? @headers[:'content-length'].to_i : nil
|
51
51
|
end
|
52
52
|
|
53
|
-
# If a
|
54
|
-
# subtype and charset. If any component of the
|
55
|
-
# its value will be `nil` in the returned triple. If the
|
53
|
+
# If a `content-type` header is set, splits it into three parts: type,
|
54
|
+
# subtype and charset. If any component of the `content-type` is missing,
|
55
|
+
# its value will be `nil` in the returned triple. If the `content-type`
|
56
56
|
# header is not set or does not match {OnStomp::Components::Frame::CONTENT_TYPE_REG}
|
57
57
|
# all values in the triple will be `nil`.
|
58
58
|
# @return [Array<String,nil>]
|
@@ -77,7 +77,7 @@ class OnStomp::Components::Frame
|
|
77
77
|
alias :headers? :all_headers?
|
78
78
|
|
79
79
|
# Returns the heart-beat configuration specified in this frame's headers.
|
80
|
-
# If a
|
80
|
+
# If a `heart-beat` header is not set, [0, 0] will be returned. Otherwise,
|
81
81
|
# the header value will be split on ',' and each component will be converted
|
82
82
|
# to a non-negative integer.
|
83
83
|
# @return [[Fixnum,Fixnum]] pair of non-negative integers that specify
|
@@ -89,7 +89,7 @@ class OnStomp::Components::Frame
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
# Sets this frame's
|
92
|
+
# Sets this frame's `content-length` header to match the byte-length of
|
93
93
|
# its body, if the body has been set.
|
94
94
|
# @return <Fixnum,nil>
|
95
95
|
def force_content_length
|
@@ -12,7 +12,7 @@ module OnStomp::Components::URI
|
|
12
12
|
def onstomp_socket_type; :tcp; end
|
13
13
|
end
|
14
14
|
|
15
|
-
# A URI class for representing URIs with a
|
15
|
+
# A URI class for representing URIs with a `stomp+ssl` scheme.
|
16
16
|
class STOMP_SSL < STOMP
|
17
17
|
# The default port to use for these kinds of URI objects when none has
|
18
18
|
# been specified.
|
@@ -14,7 +14,7 @@ class OnStomp::Connections::Base
|
|
14
14
|
|
15
15
|
# Creates a new connection using the given {#socket} object and
|
16
16
|
# {OnStomp::Client client}. The {#socket} object will generally be a `TCPSocket`
|
17
|
-
# or an
|
17
|
+
# or an `OpenSSL::SSL::SSLSocket` and must support the methods `read_nonblock`
|
18
18
|
# `write_nonblock`, and `close`.
|
19
19
|
# @param [TCPSocket,OpenSSL::SSL::SSLSocket] socket
|
20
20
|
# @param [OnStomp::Client] client
|
@@ -146,14 +146,21 @@ class OnStomp::Connections::Base
|
|
146
146
|
# sent to the head of the write buffer to be processed first the next time
|
147
147
|
# this method is invoked.
|
148
148
|
def io_process_write
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
149
|
+
begin
|
150
|
+
if @write_buffer.length > 0 && IO.select(nil, [socket], nil, 0.1)
|
151
|
+
to_shift = @write_buffer.length / 3
|
152
|
+
written = 0
|
153
|
+
while written < MAX_BYTES_PER_WRITE
|
154
|
+
data, frame = shift_write_buffer
|
155
|
+
break unless data && connected?
|
156
|
+
begin
|
157
|
+
w = socket.write_nonblock(data)
|
158
|
+
rescue Errno::EINTR, Errno::EAGAIN, Errno::EWOULDBLOCK
|
159
|
+
# writing will either block, or cannot otherwise be completed,
|
160
|
+
# put data back and try again some other day
|
161
|
+
unshift_write_buffer data, frame
|
162
|
+
break
|
163
|
+
end
|
157
164
|
written += w
|
158
165
|
@last_transmitted_at = Time.now
|
159
166
|
if w < data.length
|
@@ -162,16 +169,11 @@ class OnStomp::Connections::Base
|
|
162
169
|
yield frame if block_given?
|
163
170
|
client.dispatch_transmitted frame
|
164
171
|
end
|
165
|
-
rescue Errno::EINTR, Errno::EAGAIN, Errno::EWOULDBLOCK
|
166
|
-
# writing will either block, or cannot otherwise be completed,
|
167
|
-
# put data back and try again some other day
|
168
|
-
unshift_write_buffer data, frame
|
169
|
-
break
|
170
|
-
rescue Exception
|
171
|
-
triggered_close $!.message, :terminated
|
172
|
-
raise
|
173
172
|
end
|
174
173
|
end
|
174
|
+
rescue Exception
|
175
|
+
triggered_close $!.message, :terminated
|
176
|
+
raise
|
175
177
|
end
|
176
178
|
if @write_buffer.empty? && @closing
|
177
179
|
triggered_close 'client disconnected'
|
@@ -183,23 +185,26 @@ class OnStomp::Connections::Base
|
|
183
185
|
# to the end of a read buffer, which is then sent to the connection's
|
184
186
|
# {OnStomp::Connections::Serializers serializer} for processing.
|
185
187
|
def io_process_read
|
186
|
-
|
187
|
-
|
188
|
-
data = socket.read_nonblock(MAX_BYTES_PER_READ)
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
188
|
+
begin
|
189
|
+
if connected? && IO.select([socket], nil, nil, 0.1)
|
190
|
+
if data = socket.read_nonblock(MAX_BYTES_PER_READ)
|
191
|
+
@read_buffer << data
|
192
|
+
@last_received_at = Time.now
|
193
|
+
serializer.bytes_to_frame(@read_buffer) do |frame|
|
194
|
+
yield frame if block_given?
|
195
|
+
client.dispatch_received frame
|
196
|
+
end
|
197
|
+
else
|
198
|
+
triggered_close $!.message, :terminated
|
194
199
|
end
|
195
|
-
rescue Errno::EINTR, Errno::EAGAIN, Errno::EWOULDBLOCK
|
196
|
-
# do not
|
197
|
-
rescue EOFError
|
198
|
-
triggered_close $!.message
|
199
|
-
rescue Exception
|
200
|
-
triggered_close $!.message, :terminated
|
201
|
-
raise
|
202
200
|
end
|
201
|
+
rescue Errno::EINTR, Errno::EAGAIN, Errno::EWOULDBLOCK
|
202
|
+
# do not
|
203
|
+
rescue EOFError
|
204
|
+
triggered_close $!.message
|
205
|
+
rescue Exception
|
206
|
+
triggered_close $!.message, :terminated
|
207
|
+
raise
|
203
208
|
end
|
204
209
|
end
|
205
210
|
|
@@ -207,7 +212,7 @@ class OnStomp::Connections::Base
|
|
207
212
|
def triggered_close msg, *evs
|
208
213
|
@connection_up = false
|
209
214
|
@closing = false
|
210
|
-
socket.close
|
215
|
+
socket.close rescue nil
|
211
216
|
evs.each { |ev| trigger_connection_event ev, msg }
|
212
217
|
trigger_connection_event :closed, msg
|
213
218
|
@write_buffer.clear
|
@@ -71,7 +71,7 @@ module OnStomp::Connections::Serializers::Stomp_1
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
# Adds the substring
|
74
|
+
# Adds the substring `data[0...idx]` to the parser's accumulator,
|
75
75
|
# unshifts the remaining data back onto the buffer, and calls `meth`
|
76
76
|
# with the parser's accumulated string.
|
77
77
|
# @param [Array<String>] buffer
|
@@ -64,7 +64,7 @@ class OnStomp::Connections::Serializers::Stomp_1_1
|
|
64
64
|
unescape_header(str[(col+1)..-1]) ]
|
65
65
|
end
|
66
66
|
|
67
|
-
# Forces the frame's body to match the charset specified in its
|
67
|
+
# Forces the frame's body to match the charset specified in its `content-type`
|
68
68
|
# header, if applicable.
|
69
69
|
# @param [OnStomp::Components::Frame] frame
|
70
70
|
def prepare_parsed_frame frame
|
@@ -94,7 +94,7 @@ class OnStomp::Connections::Serializers::Stomp_1_1
|
|
94
94
|
f.body.force_encoding(charset)
|
95
95
|
f
|
96
96
|
end
|
97
|
-
# Set an appropriate
|
97
|
+
# Set an appropriate `content-type` header with `charset` parameter for
|
98
98
|
# frames with a text body
|
99
99
|
# @note No-op for Ruby 1.8.x
|
100
100
|
# @param [OnStomp::Components::Frame] f
|
@@ -19,12 +19,12 @@ class OnStomp::Failover::Client
|
|
19
19
|
# @return [Class]
|
20
20
|
attr_configurable_buffer :buffer
|
21
21
|
# The delay in seconds to wait between connection retries.
|
22
|
-
# Defaults to
|
22
|
+
# Defaults to `10`
|
23
23
|
# @return [Fixnum]
|
24
24
|
attr_configurable_int :retry_delay, :default => 10
|
25
25
|
# The maximum number of times to retry connecting during a reconnect
|
26
26
|
# loop. A non-positive number will force the failover client to try to
|
27
|
-
# reconnect indefinitely. Defaults to
|
27
|
+
# reconnect indefinitely. Defaults to `0`
|
28
28
|
# @return [Fixnum]
|
29
29
|
attr_configurable_int :retry_attempts, :default => 0
|
30
30
|
# Whether or not to randomize the {#client_pool} before connecting through
|
@@ -50,6 +50,14 @@ class OnStomp::Failover::Client
|
|
50
50
|
@connection = nil
|
51
51
|
@frame_buffer = buffer.new self
|
52
52
|
@disconnecting = false
|
53
|
+
@retry_thread = Thread.new do
|
54
|
+
until @disconnecting
|
55
|
+
Thread.stop
|
56
|
+
@client_mutex.synchronize {
|
57
|
+
reconnect unless @disconnecting
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
53
61
|
end
|
54
62
|
|
55
63
|
# Returns true if there is an {#active_client} and it is
|
@@ -69,7 +77,7 @@ class OnStomp::Failover::Client
|
|
69
77
|
# @return [self]
|
70
78
|
def connect
|
71
79
|
@disconnecting = false
|
72
|
-
unless reconnect
|
80
|
+
unless @client_mutex.synchronize { reconnect }
|
73
81
|
raise OnStomp::Failover::MaximumRetriesExceededError
|
74
82
|
end
|
75
83
|
self
|
@@ -78,43 +86,35 @@ class OnStomp::Failover::Client
|
|
78
86
|
# Ensures that a connection is properly established, then invokes
|
79
87
|
# {OnStomp::Client#disconnect disconnect} on the {#active_client}
|
80
88
|
def disconnect *args, &block
|
81
|
-
|
82
|
-
|
83
|
-
#@disconnecting = [args, block]
|
84
|
-
#if connected?
|
89
|
+
if active_client
|
90
|
+
Thread.pass until connected?
|
85
91
|
@client_mutex.synchronize do
|
86
92
|
@disconnecting = true
|
87
93
|
active_client.disconnect *args, &block
|
88
94
|
end
|
89
|
-
|
95
|
+
end
|
90
96
|
end
|
91
97
|
|
92
98
|
private
|
93
99
|
def reconnect
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
trigger_failover_event :connect_failure, :on, active_client, $!.message
|
106
|
-
end
|
107
|
-
trigger_failover_retry :after, attempt
|
108
|
-
attempt += 1
|
100
|
+
attempt = 1
|
101
|
+
until connected? || retry_exceeded?(attempt)
|
102
|
+
sleep_for_retry attempt
|
103
|
+
begin
|
104
|
+
trigger_failover_retry :before, attempt
|
105
|
+
@active_client = client_pool.next_client
|
106
|
+
# `reconnect` could be called again within the marked range.
|
107
|
+
active_client.connect # <--- From here
|
108
|
+
@connection = active_client.connection
|
109
|
+
rescue Exception
|
110
|
+
trigger_failover_event :connect_failure, :on, active_client, $!.message
|
109
111
|
end
|
110
|
-
|
111
|
-
|
112
|
-
#if @disconnecting.is_a?(Array)
|
113
|
-
# args, block = @disconnect
|
114
|
-
# active_client.disconnect *args, &block
|
115
|
-
#end
|
116
|
-
end # <--- Until here
|
112
|
+
trigger_failover_retry :after, attempt
|
113
|
+
attempt += 1
|
117
114
|
end
|
115
|
+
connected?.tap do |b|
|
116
|
+
b && trigger_failover_event(:connected, :on, active_client)
|
117
|
+
end # <--- Until here
|
118
118
|
end
|
119
119
|
|
120
120
|
def retry_exceeded? attempt
|
@@ -128,9 +128,14 @@ class OnStomp::Failover::Client
|
|
128
128
|
def create_client_pool hosts
|
129
129
|
@client_pool = pool.new hosts
|
130
130
|
on_connection_closed do |client, *_|
|
131
|
-
|
132
|
-
|
133
|
-
|
131
|
+
if client == active_client
|
132
|
+
unless @disconnecting
|
133
|
+
trigger_failover_event(:lost, :on, active_client)
|
134
|
+
# Wake up the reconnect thread. This ensures that subsequent
|
135
|
+
# connections are all spawned from the same source.
|
136
|
+
# Previously, we re-spawned here and that was rather problematic.
|
137
|
+
@retry_thread.run
|
138
|
+
end
|
134
139
|
end
|
135
140
|
end
|
136
141
|
end
|
@@ -23,9 +23,9 @@ module OnStomp::Failover::FailoverConfigurable
|
|
23
23
|
|
24
24
|
# Creates readable and writeable attributes that are automatically
|
25
25
|
# converted into boolean values. Assigning the attributes any of
|
26
|
-
# `true`,
|
26
|
+
# `true`, `'true'`, `'1'` or `1` will set the attribute to `true`, all
|
27
27
|
# other values with be treated as `false`. This method will also alias
|
28
|
-
# the reader methods with
|
28
|
+
# the reader methods with `attr_name?`
|
29
29
|
def attr_configurable_bool *args, &block
|
30
30
|
trans = attr_configurable_wrap lambda { |v|
|
31
31
|
[true, 'true', '1', 1].include?(v) }, block
|
@@ -4,8 +4,8 @@
|
|
4
4
|
module OnStomp::Failover::FailoverEvents
|
5
5
|
include OnStomp::Interfaces::EventManager
|
6
6
|
|
7
|
-
# We do this one using
|
8
|
-
# because we need
|
7
|
+
# We do this one using `class << self` instead of the `self.included` hook
|
8
|
+
# because we need `create_client_event_method` immediately.
|
9
9
|
class << self
|
10
10
|
# Creates a forwarded binding for client events.
|
11
11
|
def create_client_event_method name
|
@@ -83,6 +83,11 @@ module OnStomp::Failover::FailoverEvents
|
|
83
83
|
# @yieldparam [OnStomp::Failover::Client] failover
|
84
84
|
# @yieldparam [OnStomp::Client] client
|
85
85
|
create_event_methods :failover_connected, :on
|
86
|
+
# Binds a callback to be invoked when the maximum retries has been
|
87
|
+
# exceeded.
|
88
|
+
# @yield [failover] callback invoked when event is triggered
|
89
|
+
# @yieldparam [OnStomp::Failover::Client] failover
|
90
|
+
create_event_methods :failover_retries_exceeded, :on
|
86
91
|
|
87
92
|
# Triggers a failover retry event
|
88
93
|
def trigger_failover_retry pref, attempt
|
data/lib/onstomp/failover/uri.rb
CHANGED
@@ -27,12 +27,12 @@ module OnStomp::Failover::URI
|
|
27
27
|
class << self
|
28
28
|
# Parses a failover URI string or an array of URIs into a
|
29
29
|
# {OnStomp::Failover::URI::FAILOVER} object. Ruby's URI parser works
|
30
|
-
# fine with
|
31
|
-
# on
|
30
|
+
# fine with `failover:(uri1,uri2,..)?params=..` style URIs, but chokes
|
31
|
+
# on `failover://uri1,uri2,..` forms. This method gives us a bit more
|
32
32
|
# flexibility.
|
33
|
-
# @note If you are using the
|
34
|
-
# MUST use the
|
35
|
-
# relies on
|
33
|
+
# @note If you are using the `open-uri` extension with `failover`, you
|
34
|
+
# MUST use the `failover:(uri1,uri2,..)` form because `open-uri`
|
35
|
+
# relies on `URI.parse` to convert strings into `URI` objects.
|
36
36
|
# @overload parse(str)
|
37
37
|
# @param [String] str
|
38
38
|
# @return [FAILOVER]
|
data/lib/onstomp/failover.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Namespace for failover extensions.
|
4
4
|
module OnStomp::Failover
|
5
5
|
# Raised if the supplied failover: URI is not properly formatted as
|
6
|
-
#
|
6
|
+
# `failover:(uri,uri,...)?optionalParams=values`
|
7
7
|
class InvalidFailoverURIError < OnStomp::OnStompError; end
|
8
8
|
|
9
9
|
# Raised if the maximum number of retries is exceed when calling
|
@@ -158,7 +158,7 @@ module OnStomp::Interfaces::ClientEvents
|
|
158
158
|
end
|
159
159
|
|
160
160
|
# Triggers the :before_receiving event and the
|
161
|
-
# `before` prefixed frame specific event (eg:
|
161
|
+
# `before` prefixed frame specific event (eg: `:before_error`).
|
162
162
|
# @param [OnStomp::Components::Frame] f
|
163
163
|
def trigger_before_receiving f
|
164
164
|
trigger_event :before_receiving, f, self
|
@@ -166,7 +166,7 @@ module OnStomp::Interfaces::ClientEvents
|
|
166
166
|
end
|
167
167
|
|
168
168
|
# Triggers the :after_receiving event and the
|
169
|
-
# `on` prefixed frame specific event (eg:
|
169
|
+
# `on` prefixed frame specific event (eg: `:on_message`)
|
170
170
|
# @param [OnStomp::Components::Frame] f
|
171
171
|
def trigger_after_receiving f
|
172
172
|
trigger_event :after_receiving, f, self
|
@@ -174,7 +174,7 @@ module OnStomp::Interfaces::ClientEvents
|
|
174
174
|
end
|
175
175
|
|
176
176
|
# Triggers the :before_transmitting event and the
|
177
|
-
# `before` prefixed frame specific event (eg:
|
177
|
+
# `before` prefixed frame specific event (eg: `:before_disconnect`).
|
178
178
|
# @param [OnStomp::Components::Frame] f
|
179
179
|
def trigger_before_transmitting f
|
180
180
|
trigger_event :before_transmitting, f, self
|
@@ -182,7 +182,7 @@ module OnStomp::Interfaces::ClientEvents
|
|
182
182
|
end
|
183
183
|
|
184
184
|
# Triggers the :after_transmitting event and the
|
185
|
-
# `on` prefixed frame specific event (eg:
|
185
|
+
# `on` prefixed frame specific event (eg: `:on_send`).
|
186
186
|
# @param [OnStomp::Components::Frame] f
|
187
187
|
def trigger_after_transmitting f
|
188
188
|
trigger_event :after_transmitting, f, self
|
@@ -12,7 +12,7 @@ module OnStomp::Interfaces::ConnectionEvents
|
|
12
12
|
# @yield [client, connection] callback invoked when event is triggered
|
13
13
|
# @yieldparam [OnStomp::Client] client
|
14
14
|
# @yieldparam [OnStomp::Connections::Base] connection that triggered
|
15
|
-
# the event (in general the same as
|
15
|
+
# the event (in general the same as `client.connection`)
|
16
16
|
create_event_methods :established, :on
|
17
17
|
# @api gem:1 STOMP:1.1
|
18
18
|
# Binds a callback to be invoked when a connection has been died due to
|
@@ -21,7 +21,7 @@ module OnStomp::Interfaces::ConnectionEvents
|
|
21
21
|
# @yield [client, connection] callback invoked when event is triggered
|
22
22
|
# @yieldparam [OnStomp::Client] client
|
23
23
|
# @yieldparam [OnStomp::Connections::Base] connection that triggered
|
24
|
-
# the event (in general the same as
|
24
|
+
# the event (in general the same as `client.connection`)
|
25
25
|
create_event_methods :died, :on
|
26
26
|
# @api gem:1 STOMP:1.0,1.1
|
27
27
|
# Binds a callback to be invoked when a connection has been terminated
|
@@ -29,7 +29,7 @@ module OnStomp::Interfaces::ConnectionEvents
|
|
29
29
|
# @yield [client, connection] callback invoked when event is triggered
|
30
30
|
# @yieldparam [OnStomp::Client] client
|
31
31
|
# @yieldparam [OnStomp::Connections::Base] connection that triggered
|
32
|
-
# the event (in general the same as
|
32
|
+
# the event (in general the same as `client.connection`)
|
33
33
|
create_event_methods :terminated, :on
|
34
34
|
# @api gem:1 STOMP:1.0,1.1
|
35
35
|
# Binds a callback to be invoked when a connection has been closed, either
|
@@ -39,7 +39,7 @@ module OnStomp::Interfaces::ConnectionEvents
|
|
39
39
|
# @yield [client, connection] callback invoked when event is triggered
|
40
40
|
# @yieldparam [OnStomp::Client] client
|
41
41
|
# @yieldparam [OnStomp::Connections::Base] connection that triggered
|
42
|
-
# the event (in general the same as
|
42
|
+
# the event (in general the same as `client.connection`)
|
43
43
|
create_event_methods :closed, :on
|
44
44
|
|
45
45
|
# @endgroup
|
@@ -64,7 +64,7 @@ module OnStomp::Interfaces::FrameMethods
|
|
64
64
|
# @api gem:1 STOMP:1.0,1.1* [+ack:client-individual]
|
65
65
|
# Transmits a SUBSCRIBE frame generated by the client's connection. Depending
|
66
66
|
# upon the connection, a subscription can be set to various MESSAGE
|
67
|
-
# acknowledgement modes by setting the
|
67
|
+
# acknowledgement modes by setting the `:ack` header.
|
68
68
|
# STOMP 1.0 and STOMP 1.1 connections support:
|
69
69
|
# * :ack => 'auto'
|
70
70
|
# The broker assumes that MESSAGE frames received through the
|
@@ -239,6 +239,7 @@ module OnStomp::Interfaces::FrameMethods
|
|
239
239
|
# @api gem:1 STOMP:1.0,1.1! [+subscription:id]
|
240
240
|
# Transmits an ACK frame generated by the client's connection.
|
241
241
|
# @overload ack(message_frame, headers={})
|
242
|
+
# Generates an ACK frame for the given MESSAGE frame.
|
242
243
|
# @api gem:1 STOMP:1.0,1.1
|
243
244
|
# @note Users should use this form whenever possible as it will work
|
244
245
|
# with STOMP 1.0 and 1.1 connections.
|
@@ -246,6 +247,7 @@ module OnStomp::Interfaces::FrameMethods
|
|
246
247
|
# acknowledge.
|
247
248
|
# @param [{#to_sym => #to_s}] headers additional headers to include in
|
248
249
|
# the frame
|
250
|
+
# @return [OnStomp::Components::Frame]
|
249
251
|
# @example
|
250
252
|
# client.subscribe '/queue/test', :ack => 'client' do |m|
|
251
253
|
# if m[:'x-of-interest-to-me'] == 'hells yes'
|
@@ -253,13 +255,15 @@ module OnStomp::Interfaces::FrameMethods
|
|
253
255
|
# end
|
254
256
|
# end
|
255
257
|
# @overload ack(message_id, headers={})
|
258
|
+
# Generates an ACK frame for the given `message-id`.
|
256
259
|
# @api gem:1 STOMP:1.0
|
257
260
|
# @note This form will raise an `ArgumentError` with STOMP 1.1 connections
|
258
261
|
# as a subscription ID is also required to ACK a received MESSAGE.
|
259
|
-
# @param [String] message_id
|
262
|
+
# @param [String] message_id `message-id` header of MESSAGE frame to
|
260
263
|
# acknowledge.
|
261
264
|
# @param [{#to_sym => #to_s}] headers additional headers to include in
|
262
265
|
# the frame
|
266
|
+
# @return [OnStomp::Components::Frame]
|
263
267
|
# @example
|
264
268
|
# client.subscribe '/queue/test', :ack => 'client' do |m|
|
265
269
|
# if m[:'x-of-interest-to-me'] == 'hells yes'
|
@@ -267,15 +271,17 @@ module OnStomp::Interfaces::FrameMethods
|
|
267
271
|
# end
|
268
272
|
# end
|
269
273
|
# @overload ack(message_id, subscription_id, headers={})
|
274
|
+
# Generates an ACK frame for the given `message-id` and `subscription`.
|
270
275
|
# @api gem:1 STOMP:1.0,1.1
|
271
276
|
# @note This form should be used with STOMP 1.1 connections when it is
|
272
277
|
# not possible to provide the actual MESSAGE frame.
|
273
|
-
# @param [String] message_id
|
278
|
+
# @param [String] message_id `message-id` header of MESSAGE frame to
|
274
279
|
# acknowledge.
|
275
280
|
# @param [String] subscription_id `subscription` header of MESSAGE frame to
|
276
281
|
# acknowledge.
|
277
282
|
# @param [{#to_sym => #to_s}] headers additional headers to include in
|
278
283
|
# the frame
|
284
|
+
# @return [OnStomp::Components::Frame]
|
279
285
|
# @example
|
280
286
|
# client.subscribe '/queue/test', :ack => 'client' do |m|
|
281
287
|
# if m[:'x-of-interest-to-me'] == 'hells yes'
|
@@ -303,6 +309,7 @@ module OnStomp::Interfaces::FrameMethods
|
|
303
309
|
# un-acknowledge.
|
304
310
|
# @param [{#to_sym => #to_s}] headers additional headers to include in
|
305
311
|
# the frame
|
312
|
+
# @return [OnStomp::Components::Frame]
|
306
313
|
# @example
|
307
314
|
# client.subscribe '/queue/test', :ack => 'client' do |m|
|
308
315
|
# if m[:'x-of-interest-to-me'] == 'hells no!'
|
@@ -310,12 +317,14 @@ module OnStomp::Interfaces::FrameMethods
|
|
310
317
|
# end
|
311
318
|
# end
|
312
319
|
# @overload nack(message_id, subscription_id, heders={})
|
313
|
-
#
|
320
|
+
# Generates a NACK frame for the given `message-id` and `subscription`.
|
321
|
+
# @param [String] message_id `message-id` header of MESSAGE frame to
|
314
322
|
# un-acknowledge.
|
315
323
|
# @param [String] subscription_id `subscription` header of MESSAGE frame to
|
316
324
|
# un-acknowledge.
|
317
325
|
# @param [{#to_sym => #to_s}] headers additional headers to include in
|
318
326
|
# the frame
|
327
|
+
# @return [OnStomp::Components::Frame]
|
319
328
|
# @example
|
320
329
|
# client.subscribe '/queue/test', :ack => 'client' do |m|
|
321
330
|
# if m[:'x-of-interest-to-me'] == 'hells no!'
|
data/lib/onstomp/version.rb
CHANGED
data/onstomp.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
22
|
s.required_ruby_version = '>= 1.8.7'
|
23
|
-
s.has_rdoc = 'yard'
|
23
|
+
#s.has_rdoc = 'yard'
|
24
24
|
s.add_development_dependency('rspec', '~> 2.4.0')
|
25
25
|
s.add_development_dependency('simplecov', '>= 0.3.0')
|
26
26
|
s.add_development_dependency('yard', '>= 0.6.0')
|
@@ -58,7 +58,7 @@ describe OnStomp::Failover, "full stack test", :fullstack => true, :failover =>
|
|
58
58
|
end
|
59
59
|
client.unsubscribe sub, :'x-onstomp-real-client' => client.active_client.uri
|
60
60
|
client.commit 't-1234', :'x-onstomp-real-client' => client.active_client.uri
|
61
|
-
|
61
|
+
#Thread.pass until client.connected?
|
62
62
|
client.disconnect :'x-onstomp-real-client' => client.active_client.uri
|
63
63
|
brokers.each(&:join)
|
64
64
|
brokers.first.frames_received.map(&:command).should == ["CONNECT", "SEND", "BEGIN", "SEND", "SUBSCRIBE"]
|
@@ -96,7 +96,7 @@ describe OnStomp::Failover, "full stack test", :fullstack => true, :failover =>
|
|
96
96
|
end
|
97
97
|
client.unsubscribe sub, :'x-onstomp-real-client' => client.active_client.uri
|
98
98
|
client.commit 't-1234', :'x-onstomp-real-client' => client.active_client.uri
|
99
|
-
|
99
|
+
#Thread.pass until client.connected?
|
100
100
|
client.disconnect :'x-onstomp-real-client' => client.active_client.uri
|
101
101
|
brokers.each(&:join)
|
102
102
|
brokers.first.frames_received.map(&:command).should == ["CONNECT", "SEND", "BEGIN", "SEND", "SUBSCRIBE"]
|
@@ -4,7 +4,7 @@ require File.expand_path('../test_broker', __FILE__)
|
|
4
4
|
|
5
5
|
describe OnStomp::OpenURI, "full stack test", :fullstack => true, :openuri => true do
|
6
6
|
let(:broker) {
|
7
|
-
TestBroker.new
|
7
|
+
TestBroker.new 10101
|
8
8
|
}
|
9
9
|
before(:each) do
|
10
10
|
broker.start
|
@@ -15,7 +15,7 @@ describe OnStomp::OpenURI, "full stack test", :fullstack => true, :openuri => tr
|
|
15
15
|
|
16
16
|
describe "opening URIs" do
|
17
17
|
it "should deliver some SEND frames" do
|
18
|
-
open("stomp://localhost/queue/onstomp/open-uri/test") do |c|
|
18
|
+
open("stomp://localhost:10101/queue/onstomp/open-uri/test") do |c|
|
19
19
|
c.send "Test Message 1"
|
20
20
|
c.send "Another Test Message"
|
21
21
|
end
|
@@ -25,7 +25,7 @@ describe OnStomp::OpenURI, "full stack test", :fullstack => true, :openuri => tr
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should receive the some MESSAGE frames" do
|
28
|
-
open("stomp://localhost/queue/onstomp/open-uri/test") do |c|
|
28
|
+
open("stomp://localhost:10101/queue/onstomp/open-uri/test") do |c|
|
29
29
|
c.send "Test Message 1"
|
30
30
|
c.send "Another Test Message"
|
31
31
|
c.send "Last Message"
|
@@ -29,7 +29,6 @@ end
|
|
29
29
|
|
30
30
|
RSpec::Matchers.define :be_a_transaction_scope do |tx_id|
|
31
31
|
match do |actual|
|
32
|
-
$stdout.puts "Checking transaction? #{tx_id.inspect}"
|
33
32
|
type_check = actual.is_a?(OnStomp::Components::Scopes::TransactionScope)
|
34
33
|
tx_id ? type_check && actual.transaction == tx_id : type_check
|
35
34
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: onstomp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.0.
|
5
|
+
version: 1.0.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ian D. Eccles
|
@@ -10,8 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
14
|
-
default_executable:
|
13
|
+
date: 2011-04-20 00:00:00 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: rspec
|
@@ -195,7 +194,6 @@ files:
|
|
195
194
|
- spec/support/frame_matchers.rb
|
196
195
|
- spec/support/shared_frame_method_examples.rb
|
197
196
|
- yard_extensions.rb
|
198
|
-
has_rdoc: yard
|
199
197
|
homepage: http://github.com/meadvillerb/onstomp
|
200
198
|
licenses: []
|
201
199
|
|
@@ -219,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
217
|
requirements: []
|
220
218
|
|
221
219
|
rubyforge_project: onstomp-core
|
222
|
-
rubygems_version: 1.
|
220
|
+
rubygems_version: 1.7.2
|
223
221
|
signing_key:
|
224
222
|
specification_version: 3
|
225
223
|
summary: Client for message queues implementing the Stomp protocol interface.
|
@@ -287,3 +285,4 @@ test_files:
|
|
287
285
|
- spec/support/custom_argument_matchers.rb
|
288
286
|
- spec/support/frame_matchers.rb
|
289
287
|
- spec/support/shared_frame_method_examples.rb
|
288
|
+
has_rdoc:
|