onstomp 1.0.2 → 1.0.3
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/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:
|