stomp 1.1.5 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +4 -0
- data/lib/stomp.rb +1 -0
- data/lib/stomp/client.rb +3 -6
- data/lib/stomp/connection.rb +11 -9
- data/lib/stomp/ext/hash.rb +1 -1
- data/lib/stomp/version.rb +1 -1
- data/spec/connection_spec.rb +3 -2
- data/stomp.gemspec +2 -2
- data/test/test_client.rb +83 -10
- data/test/test_connection.rb +115 -0
- metadata +2 -2
data/CHANGELOG.rdoc
CHANGED
data/lib/stomp.rb
CHANGED
data/lib/stomp/client.rb
CHANGED
@@ -286,15 +286,12 @@ module Stomp
|
|
286
286
|
|
287
287
|
@listener_thread = Thread.start do
|
288
288
|
while true
|
289
|
-
message = @connection.
|
290
|
-
|
291
|
-
when message.nil?
|
292
|
-
sleep 0.1
|
293
|
-
when message.command == 'MESSAGE'
|
289
|
+
message = @connection.receive
|
290
|
+
if message.command == 'MESSAGE'
|
294
291
|
if listener = @listeners[message.headers['destination']]
|
295
292
|
listener.call(message)
|
296
293
|
end
|
297
|
-
|
294
|
+
elsif message.command == 'RECEIPT'
|
298
295
|
if listener = @receipt_listeners[message.headers['receipt-id']]
|
299
296
|
listener.call(message)
|
300
297
|
end
|
data/lib/stomp/connection.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'socket'
|
2
|
-
require 'monitor'
|
3
2
|
require 'timeout'
|
4
3
|
|
5
4
|
module Stomp
|
@@ -71,8 +70,11 @@ module Stomp
|
|
71
70
|
@parameters = nil
|
72
71
|
end
|
73
72
|
|
73
|
+
# Use Mutexes: only one lock per each thread
|
74
|
+
# Revert to original implementation attempt
|
74
75
|
@transmit_semaphore = Mutex.new
|
75
|
-
@read_semaphore =
|
76
|
+
@read_semaphore = Mutex.new
|
77
|
+
@socket_semaphore = Mutex.new
|
76
78
|
|
77
79
|
@subscriptions = {}
|
78
80
|
@failure = nil
|
@@ -98,7 +100,7 @@ module Stomp
|
|
98
100
|
end
|
99
101
|
|
100
102
|
def socket
|
101
|
-
@
|
103
|
+
@socket_semaphore.synchronize do
|
102
104
|
used_socket = @socket
|
103
105
|
used_socket = nil if closed?
|
104
106
|
|
@@ -154,7 +156,7 @@ module Stomp
|
|
154
156
|
end
|
155
157
|
|
156
158
|
def change_host
|
157
|
-
@parameters[:hosts].
|
159
|
+
@parameters[:hosts] = @parameters[:hosts].sort_by { rand } if @parameters[:randomize]
|
158
160
|
|
159
161
|
# Set first as master and send it to the end of array
|
160
162
|
current_host = @parameters[:hosts].shift
|
@@ -169,7 +171,7 @@ module Stomp
|
|
169
171
|
end
|
170
172
|
|
171
173
|
def max_reconnect_attempts?
|
172
|
-
!(@parameters.nil? || @parameters[:max_reconnect_attempts].nil?) && @parameters[:max_reconnect_attempts] != 0 && @connection_attempts
|
174
|
+
!(@parameters.nil? || @parameters[:max_reconnect_attempts].nil?) && @parameters[:max_reconnect_attempts] != 0 && @connection_attempts >= @parameters[:max_reconnect_attempts]
|
173
175
|
end
|
174
176
|
|
175
177
|
def increase_reconnect_delay
|
@@ -308,10 +310,10 @@ module Stomp
|
|
308
310
|
# Return a pending message if one is available, otherwise
|
309
311
|
# return nil
|
310
312
|
def poll
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
313
|
+
# No need for a read lock here. The receive method eventually fullfills
|
314
|
+
# that requirement.
|
315
|
+
return nil if @socket.nil? || !@socket.ready?
|
316
|
+
receive
|
315
317
|
end
|
316
318
|
|
317
319
|
# Receive a frame, block until the frame is received
|
data/lib/stomp/ext/hash.rb
CHANGED
data/lib/stomp/version.rb
CHANGED
data/spec/connection_spec.rb
CHANGED
@@ -334,11 +334,12 @@ describe Stomp::Connection do
|
|
334
334
|
@parameters[:max_reconnect_attempts] = limit
|
335
335
|
@connection = Stomp::Connection.new(@parameters)
|
336
336
|
|
337
|
-
@connection.instance_variable_set(:@connection_attempts, limit)
|
337
|
+
@connection.instance_variable_set(:@connection_attempts, limit-1)
|
338
338
|
@connection.max_reconnect_attempts?.should be_false
|
339
339
|
|
340
|
-
@connection.instance_variable_set(:@connection_attempts, limit
|
340
|
+
@connection.instance_variable_set(:@connection_attempts, limit)
|
341
341
|
@connection.max_reconnect_attempts?.should be_true
|
342
|
+
|
342
343
|
end
|
343
344
|
end
|
344
345
|
end
|
data/stomp.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{stomp}
|
8
|
-
s.version = "1.1.
|
8
|
+
s.version = "1.1.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian McCallister", "Marius Mathiesen", "Thiago Morello"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-06-10}
|
13
13
|
s.description = %q{Ruby client for the Stomp messaging protocol}
|
14
14
|
s.email = ["brianm@apache.org", "marius@stones.com", "morellon@gmail.com"]
|
15
15
|
s.executables = ["catstomp", "stompcat"]
|
data/test/test_client.rb
CHANGED
@@ -7,6 +7,9 @@ class TestClient < Test::Unit::TestCase
|
|
7
7
|
|
8
8
|
def setup
|
9
9
|
@client = Stomp::Client.new(user, passcode, host, port)
|
10
|
+
# Multi_thread test data
|
11
|
+
@max_threads = 20
|
12
|
+
@max_msgs = 50
|
10
13
|
end
|
11
14
|
|
12
15
|
def teardown
|
@@ -36,7 +39,6 @@ class TestClient < Test::Unit::TestCase
|
|
36
39
|
assert_equal message_text, received.body
|
37
40
|
end
|
38
41
|
|
39
|
-
# BROKEN
|
40
42
|
def test_noack
|
41
43
|
@client.publish destination, message_text
|
42
44
|
|
@@ -49,11 +51,13 @@ class TestClient < Test::Unit::TestCase
|
|
49
51
|
# was never acked so should be resent to next client
|
50
52
|
|
51
53
|
@client = Stomp::Client.new(user, passcode, host, port)
|
52
|
-
|
53
|
-
@client.subscribe(destination) {|msg|
|
54
|
-
sleep 0.01 until
|
54
|
+
received2 = nil
|
55
|
+
@client.subscribe(destination) {|msg| received2 = msg}
|
56
|
+
sleep 0.01 until received2
|
55
57
|
|
56
|
-
assert_equal message_text,
|
58
|
+
assert_equal message_text, received2.body
|
59
|
+
assert_equal received.body, received2.body
|
60
|
+
assert_equal received.headers['message-id'], received2.headers['message-id']
|
57
61
|
end
|
58
62
|
|
59
63
|
def test_receipts
|
@@ -178,13 +182,82 @@ class TestClient < Test::Unit::TestCase
|
|
178
182
|
def test_unsubscribe
|
179
183
|
message = nil
|
180
184
|
client = Stomp::Client.new(user, passcode, host, port, true)
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
+
assert_nothing_raised {
|
186
|
+
client.subscribe(destination, :ack => 'client') { |m| message = m }
|
187
|
+
@client.publish destination, message_text
|
188
|
+
Timeout::timeout(4) do
|
189
|
+
sleep 0.01 until message
|
190
|
+
end
|
191
|
+
}
|
192
|
+
assert_equal message_text, message.body
|
193
|
+
assert_nothing_raised {
|
194
|
+
client.unsubscribe destination # was throwing exception on unsub at one point
|
195
|
+
client.close
|
196
|
+
}
|
197
|
+
# Same message should remain on the queue. Receive it again with ack=>auto.
|
198
|
+
message_copy = nil
|
199
|
+
client = Stomp::Client.new(user, passcode, host, port, true)
|
200
|
+
assert_nothing_raised {
|
201
|
+
client.subscribe(destination, :ack => 'auto') { |m| message_copy = m }
|
202
|
+
Timeout::timeout(4) do
|
203
|
+
sleep 0.01 until message_copy
|
204
|
+
end
|
205
|
+
}
|
206
|
+
assert_equal message_text, message_copy.body
|
207
|
+
assert_equal message.headers['message-id'], message_copy.headers['message-id']
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_thread_one_subscribe
|
211
|
+
msg = nil
|
212
|
+
Thread.new(@client) do |acli|
|
213
|
+
assert_nothing_raised {
|
214
|
+
acli.subscribe(destination) { |m| msg = m }
|
215
|
+
Timeout::timeout(4) do
|
216
|
+
sleep 0.01 until msg
|
217
|
+
end
|
218
|
+
}
|
185
219
|
end
|
186
|
-
|
220
|
+
#
|
221
|
+
@client.publish(destination, message_text)
|
222
|
+
sleep 1
|
223
|
+
assert_not_nil msg
|
224
|
+
end
|
187
225
|
|
226
|
+
def test_thread_multi_subscribe
|
227
|
+
#
|
228
|
+
lock = Mutex.new
|
229
|
+
msg_ctr = 0
|
230
|
+
1.upto(@max_threads) do |tnum|
|
231
|
+
# Threads within threads .....
|
232
|
+
Thread.new(@client) do |acli|
|
233
|
+
assert_nothing_raised {
|
234
|
+
acli.subscribe(destination) { |m|
|
235
|
+
msg = m
|
236
|
+
lock.synchronize do
|
237
|
+
msg_ctr += 1
|
238
|
+
end
|
239
|
+
# Simulate message processing
|
240
|
+
sleep 0.05
|
241
|
+
}
|
242
|
+
}
|
243
|
+
end
|
244
|
+
end
|
245
|
+
#
|
246
|
+
1.upto(@max_msgs) do |mnum|
|
247
|
+
msg = Time.now.to_s + " #{mnum}"
|
248
|
+
@client.publish(destination, message_text)
|
249
|
+
end
|
250
|
+
#
|
251
|
+
max_sleep=5
|
252
|
+
sleep_incr = 0.10
|
253
|
+
total_slept = 0
|
254
|
+
while true
|
255
|
+
break if @max_msgs == msg_ctr
|
256
|
+
total_slept += sleep_incr
|
257
|
+
break if total_slept > max_sleep
|
258
|
+
sleep sleep_incr
|
259
|
+
end
|
260
|
+
assert_equal @max_msgs, msg_ctr
|
188
261
|
end
|
189
262
|
|
190
263
|
private
|
data/test/test_connection.rb
CHANGED
@@ -7,6 +7,9 @@ class TestStomp < Test::Unit::TestCase
|
|
7
7
|
|
8
8
|
def setup
|
9
9
|
@conn = Stomp::Connection.open(user, passcode, host, port)
|
10
|
+
# Data for multi_thread tests
|
11
|
+
@max_threads = 20
|
12
|
+
@max_msgs = 100
|
10
13
|
end
|
11
14
|
|
12
15
|
def teardown
|
@@ -107,6 +110,117 @@ class TestStomp < Test::Unit::TestCase
|
|
107
110
|
assert_equal "b\0", msg_b.body
|
108
111
|
end
|
109
112
|
|
113
|
+
def test_thread_hang_one
|
114
|
+
received = nil
|
115
|
+
Thread.new(@conn) do |amq|
|
116
|
+
while true
|
117
|
+
received = amq.receive
|
118
|
+
end
|
119
|
+
end
|
120
|
+
#
|
121
|
+
@conn.subscribe( make_destination )
|
122
|
+
message = Time.now.to_s
|
123
|
+
@conn.publish(make_destination, message)
|
124
|
+
sleep 1
|
125
|
+
assert_not_nil received
|
126
|
+
assert_equal message, received.body
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_thread_poll_one
|
130
|
+
received = nil
|
131
|
+
Thread.new(@conn) do |amq|
|
132
|
+
while true
|
133
|
+
received = amq.poll
|
134
|
+
# One message is needed
|
135
|
+
Thread.exit if received
|
136
|
+
sleep 0.1
|
137
|
+
end
|
138
|
+
end
|
139
|
+
#
|
140
|
+
@conn.subscribe( make_destination )
|
141
|
+
message = Time.now.to_s
|
142
|
+
@conn.publish(make_destination, message)
|
143
|
+
sleep 1
|
144
|
+
assert_not_nil received
|
145
|
+
assert_equal message, received.body
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_multi_thread_receive
|
149
|
+
lock = Mutex.new
|
150
|
+
msg_ctr = 0
|
151
|
+
#
|
152
|
+
1.upto(@max_threads) do |tnum|
|
153
|
+
Thread.new(@conn) do |amq|
|
154
|
+
while true
|
155
|
+
received = amq.receive
|
156
|
+
lock.synchronize do
|
157
|
+
msg_ctr += 1
|
158
|
+
end
|
159
|
+
# Simulate message processing
|
160
|
+
sleep 0.05
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
#
|
165
|
+
@conn.subscribe( make_destination )
|
166
|
+
1.upto(@max_msgs) do |mnum|
|
167
|
+
msg = Time.now.to_s + " #{mnum}"
|
168
|
+
@conn.publish(make_destination, msg)
|
169
|
+
end
|
170
|
+
#
|
171
|
+
max_sleep=5
|
172
|
+
sleep_incr = 0.10
|
173
|
+
total_slept = 0
|
174
|
+
while true
|
175
|
+
break if @max_msgs == msg_ctr
|
176
|
+
total_slept += sleep_incr
|
177
|
+
break if total_slept > max_sleep
|
178
|
+
sleep sleep_incr
|
179
|
+
end
|
180
|
+
assert_equal @max_msgs, msg_ctr
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_multi_thread_poll
|
184
|
+
#
|
185
|
+
lock = Mutex.new
|
186
|
+
msg_ctr = 0
|
187
|
+
#
|
188
|
+
1.upto(@max_threads) do |tnum|
|
189
|
+
Thread.new(@conn) do |amq|
|
190
|
+
while true
|
191
|
+
received = amq.poll
|
192
|
+
if received
|
193
|
+
lock.synchronize do
|
194
|
+
msg_ctr += 1
|
195
|
+
end
|
196
|
+
# Simulate message processing
|
197
|
+
sleep 0.05
|
198
|
+
else
|
199
|
+
# Wait a bit for more work
|
200
|
+
sleep 0.05
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
#
|
206
|
+
@conn.subscribe( make_destination )
|
207
|
+
1.upto(@max_msgs) do |mnum|
|
208
|
+
msg = Time.now.to_s + " #{mnum}"
|
209
|
+
@conn.publish(make_destination, msg)
|
210
|
+
end
|
211
|
+
#
|
212
|
+
max_sleep=5
|
213
|
+
sleep_incr = 0.10
|
214
|
+
total_slept = 0
|
215
|
+
while true
|
216
|
+
break if @max_msgs == msg_ctr
|
217
|
+
total_slept += sleep_incr
|
218
|
+
break if total_slept > max_sleep
|
219
|
+
sleep sleep_incr
|
220
|
+
end
|
221
|
+
assert_equal @max_msgs, msg_ctr
|
222
|
+
end
|
223
|
+
|
110
224
|
private
|
111
225
|
def make_destination
|
112
226
|
"/queue/test/ruby/stomp/" + name
|
@@ -133,3 +247,4 @@ class TestStomp < Test::Unit::TestCase
|
|
133
247
|
assert_equal "txn message", msg.body
|
134
248
|
end
|
135
249
|
end
|
250
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stomp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian McCallister
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2010-
|
14
|
+
date: 2010-06-10 00:00:00 -03:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|