reliable-msg 1.0.0 → 1.0.1
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/README +2 -2
- data/Rakefile +1 -2
- data/lib/reliable-msg.rb +1 -1
- data/lib/reliable-msg/cli.rb +47 -35
- data/lib/reliable-msg/message-store.rb +16 -17
- data/lib/reliable-msg/queue-manager.rb +3 -0
- data/test/test-queue.rb +46 -9
- metadata +2 -2
data/README
CHANGED
@@ -26,7 +26,7 @@ The latest version of Reliable Messaging can be found at
|
|
26
26
|
|
27
27
|
* http://rubyforge.org/projects/reliable-msg/
|
28
28
|
|
29
|
-
For more information
|
29
|
+
For more information
|
30
30
|
|
31
31
|
* http://trac.labnotes.org/cgi-bin/trac.cgi/wiki/RubyReliableMessaging
|
32
32
|
|
@@ -36,7 +36,7 @@ For more information (wiki, bug reports)
|
|
36
36
|
You can download the sources directly, or install the GEM package
|
37
37
|
(recommended) with
|
38
38
|
|
39
|
-
gem install
|
39
|
+
gem install reliable-msg
|
40
40
|
|
41
41
|
To create the configuration file and queues for use with the disk-based
|
42
42
|
message store
|
data/Rakefile
CHANGED
@@ -123,7 +123,7 @@ EOF
|
|
123
123
|
end
|
124
124
|
|
125
125
|
gem = Rake::GemPackageTask.new(gem_spec) do |pkg|
|
126
|
-
pkg.
|
126
|
+
pkg.need_tar = true
|
127
127
|
pkg.need_zip = true
|
128
128
|
end
|
129
129
|
|
@@ -161,4 +161,3 @@ task :update_version => [:prerelease] do
|
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
|
-
|
data/lib/reliable-msg.rb
CHANGED
data/lib/reliable-msg/cli.rb
CHANGED
@@ -21,43 +21,50 @@ module ReliableMsg
|
|
21
21
|
class CLI #:nodoc:
|
22
22
|
|
23
23
|
USAGE = <<-EOF
|
24
|
-
usage: queues
|
24
|
+
usage: queues command [args] [options]
|
25
25
|
|
26
26
|
To see list of available commands and options
|
27
27
|
queues help
|
28
28
|
EOF
|
29
29
|
|
30
30
|
HELP = <<-EOF
|
31
|
-
usage: queues
|
31
|
+
usage: queues command [args] [options]
|
32
32
|
|
33
33
|
Reliable messaging queue manager, version #{VERSION}
|
34
34
|
|
35
35
|
Available commands:
|
36
36
|
|
37
|
-
help
|
38
|
-
|
37
|
+
help
|
38
|
+
Display this help message.
|
39
39
|
|
40
|
-
manager start
|
41
|
-
|
40
|
+
manager start
|
41
|
+
Start the queue manager as a standalone server
|
42
42
|
|
43
|
-
manager stop
|
44
|
-
|
43
|
+
manager stop
|
44
|
+
Stop a running queue manager.
|
45
45
|
|
46
|
-
install disk [<path>]
|
47
|
-
|
48
|
-
|
46
|
+
install disk [<path>]
|
47
|
+
Configure queue manager to use disk-based message store
|
48
|
+
using the specified directory. Uses 'queues' by default.
|
49
49
|
|
50
|
-
install mysql <host> <username> <password> <database> [options]
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
install mysql <host> <username> <password> <database> [options]
|
51
|
+
[--port <port>] [--socket <socket>] [--prefix <prefix>]
|
52
|
+
Configure queue manager to use MySQL for message store,
|
53
|
+
using the specified connection properties. Updates database
|
54
|
+
schema.
|
55
55
|
|
56
|
-
|
56
|
+
--port Port to connect to
|
57
|
+
--socket Socket to connect to
|
58
|
+
--prefix Prefix for table names
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
-
|
60
|
+
|
61
|
+
Available options:
|
62
|
+
|
63
|
+
-v --version
|
64
|
+
Show version number.
|
65
|
+
|
66
|
+
-c --config <path>
|
67
|
+
Points to the queue manager configuration file.
|
61
68
|
|
62
69
|
EOF
|
63
70
|
|
@@ -101,22 +108,10 @@ EOF
|
|
101
108
|
manager.stop
|
102
109
|
end
|
103
110
|
when 'stop'
|
104
|
-
if config_file
|
105
|
-
config = Config.new config_file, nil
|
106
|
-
unless config.load_no_create || config_file.nil?
|
107
|
-
puts "Could not find configuration file #{config.path}"
|
108
|
-
exit
|
109
|
-
end
|
110
|
-
drb = Config::DEFAULT_DRB
|
111
|
-
drb.merge(config.drb) if config.drb
|
112
|
-
drb_uri = "druby://localhost:#{drb['port']}"
|
113
|
-
else
|
114
|
-
drb_uri = Queue::DEFAULT_DRB
|
115
|
-
end
|
116
111
|
begin
|
117
|
-
|
112
|
+
queue_manager(config_file).stop
|
118
113
|
rescue DRb::DRbConnError =>error
|
119
|
-
puts "
|
114
|
+
puts "Cannot access queue manager: is it running?"
|
120
115
|
end
|
121
116
|
else
|
122
117
|
raise InvalidUsage
|
@@ -153,14 +148,31 @@ EOF
|
|
153
148
|
else
|
154
149
|
raise InvalidUsage
|
155
150
|
end
|
151
|
+
|
156
152
|
else
|
157
153
|
raise InvalidUsage
|
158
|
-
|
154
|
+
end
|
159
155
|
rescue InvalidUsage
|
160
156
|
puts USAGE
|
161
157
|
end
|
162
158
|
end
|
163
159
|
|
160
|
+
def queue_manager config_file
|
161
|
+
if config_file
|
162
|
+
config = Config.new config_file, nil
|
163
|
+
unless config.load_no_create || config_file.nil?
|
164
|
+
puts "Could not find configuration file #{config.path}"
|
165
|
+
exit
|
166
|
+
end
|
167
|
+
drb = Config::DEFAULT_DRB
|
168
|
+
drb.merge(config.drb) if config.drb
|
169
|
+
drb_uri = "druby://localhost:#{drb['port']}"
|
170
|
+
else
|
171
|
+
drb_uri = Queue::DEFAULT_DRB_URI
|
172
|
+
end
|
173
|
+
DRbObject.new(nil, drb_uri)
|
174
|
+
end
|
175
|
+
|
164
176
|
end
|
165
177
|
|
166
178
|
end
|
@@ -8,6 +8,8 @@
|
|
8
8
|
#
|
9
9
|
#--
|
10
10
|
# Changes:
|
11
|
+
# 11/11/05
|
12
|
+
# Fixed: Messages retrieved in order after queue manager recovers when using MySQL.
|
11
13
|
#++
|
12
14
|
|
13
15
|
require 'thread'
|
@@ -132,17 +134,15 @@ module ReliableMsg
|
|
132
134
|
headers = insert[:headers]
|
133
135
|
# Add element based on priority, higher priority comes first.
|
134
136
|
priority = headers[:priority]
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
137
|
+
added = false
|
138
|
+
queue.each_index do |idx|
|
139
|
+
if queue[idx][:priority] < priority
|
140
|
+
queue[idx, 0] = headers
|
141
|
+
added = true
|
142
|
+
break
|
141
143
|
end
|
142
|
-
queue << headers
|
143
|
-
else
|
144
|
-
queue << headers
|
145
144
|
end
|
145
|
+
queue << headers unless added
|
146
146
|
@cache[insert[:id]] = insert[:message]
|
147
147
|
end
|
148
148
|
deletes.each do |delete|
|
@@ -470,16 +470,15 @@ module ReliableMsg
|
|
470
470
|
headers = Marshal::load row[2]
|
471
471
|
# Add element based on priority, higher priority comes first.
|
472
472
|
priority = headers[:priority]
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
473
|
+
added = false
|
474
|
+
queue.each_index do |idx|
|
475
|
+
if queue[idx][:priority] < priority
|
476
|
+
queue[idx, 0] = headers
|
477
|
+
added = true
|
478
|
+
break
|
479
479
|
end
|
480
|
-
else
|
481
|
-
queue << headers
|
482
480
|
end
|
481
|
+
queue << headers unless added
|
483
482
|
end
|
484
483
|
end
|
485
484
|
end
|
@@ -8,6 +8,8 @@
|
|
8
8
|
#
|
9
9
|
#--
|
10
10
|
# Changes:
|
11
|
+
# 11/11/05
|
12
|
+
# Fixed: Stop/start queue manager.
|
11
13
|
#++
|
12
14
|
|
13
15
|
require 'singleton'
|
@@ -192,6 +194,7 @@ module ReliableMsg
|
|
192
194
|
def stop
|
193
195
|
@mutex.synchronize do
|
194
196
|
return unless @started
|
197
|
+
@started = false
|
195
198
|
|
196
199
|
# Prevent transactions from timing out while we take down the server.
|
197
200
|
@timeout_thread.terminate
|
data/test/test-queue.rb
CHANGED
@@ -22,28 +22,44 @@ class TestQueue < Test::Unit::TestCase
|
|
22
22
|
@dlq = ReliableMsg::Queue.new ReliableMsg::Queue::DLQ
|
23
23
|
@manager = ReliableMsg::QueueManager.new
|
24
24
|
@manager.start
|
25
|
-
clear
|
25
|
+
clear false
|
26
|
+
@restart = proc do
|
27
|
+
@manager.stop
|
28
|
+
@manager.start
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
def teardown
|
33
|
+
clear true
|
29
34
|
@manager.stop
|
30
35
|
end
|
31
36
|
|
32
37
|
def test_order
|
33
|
-
|
38
|
+
# Run test case without restrating queue manager (from cache).
|
39
|
+
_test_order
|
40
|
+
# Run test case by restarting queue manager (test recovery).
|
41
|
+
_test_order @restart
|
42
|
+
end
|
43
|
+
|
44
|
+
def _test_order restart = nil
|
34
45
|
# Put two messages, test that they are retrieved in order.
|
35
46
|
id1 = @queue.put 'first test message'
|
36
47
|
id2 = @queue.put 'second test message'
|
48
|
+
restart.call if restart
|
49
|
+
# TODO: order is not really guaranteed here.
|
37
50
|
msg = @queue.get
|
38
|
-
assert msg && msg.id == id1, "Failed to retrieve message in order"
|
51
|
+
assert msg && (msg.id == id1 || msg.id == id2), "Failed to retrieve message in order"
|
52
|
+
seen = msg.id
|
39
53
|
msg = @queue.get
|
40
|
-
assert msg && msg.id == id2, "Failed to retrieve message in order"
|
54
|
+
assert msg && (msg.id == id1 || msg.id == id2), "Failed to retrieve message in order"
|
55
|
+
assert msg.id != seen, "Retrieved the same message twice"
|
41
56
|
assert @queue.get.nil?, "Phantom message in queue"
|
42
57
|
|
43
58
|
# Put three messages with priority, test that they are retrieved in order.
|
44
59
|
id1 = @queue.put 'priority one message', :priority=>1
|
45
60
|
id2 = @queue.put 'priority three message', :priority=>3
|
46
61
|
id3 = @queue.put 'priority two message', :priority=>2
|
62
|
+
restart.call if restart
|
47
63
|
msg = @queue.get
|
48
64
|
assert msg && msg.id == id2, "Failed to retrieve message in order"
|
49
65
|
msg = @queue.get
|
@@ -54,11 +70,18 @@ class TestQueue < Test::Unit::TestCase
|
|
54
70
|
end
|
55
71
|
|
56
72
|
def test_selector
|
57
|
-
|
73
|
+
# Run test case without restrating queue manager (from cache).
|
74
|
+
_test_selector
|
75
|
+
# Run test case by restarting queue manager (test recovery).
|
76
|
+
_test_selector @restart
|
77
|
+
end
|
78
|
+
|
79
|
+
def _test_selector restart = nil
|
58
80
|
# Test that we can retrieve message based on specific header value,
|
59
81
|
# contrary to queue order.
|
60
82
|
id1 = @queue.put 'first test message', :name=>"foo"
|
61
83
|
id2 = @queue.put 'second test message', :name=>"bar"
|
84
|
+
restart.call if restart
|
62
85
|
msg = @queue.get(ReliableMsg::Queue.selector { name == 'bar' })
|
63
86
|
assert msg && msg.id == id2, "Failed to retrieve message by selector"
|
64
87
|
msg = @queue.get(ReliableMsg::Queue.selector { name == 'foo' })
|
@@ -67,12 +90,19 @@ class TestQueue < Test::Unit::TestCase
|
|
67
90
|
end
|
68
91
|
|
69
92
|
def test_non_delivered
|
70
|
-
|
93
|
+
# Run test case without restrating queue manager (from cache).
|
94
|
+
_test_non_delivered
|
95
|
+
# Run test case by restarting queue manager (test recovery).
|
96
|
+
_test_non_delivered @restart
|
97
|
+
end
|
98
|
+
|
99
|
+
def _test_non_delivered restart = nil
|
71
100
|
# Test that we can receive message that has not yet expired (30 second delay),
|
72
101
|
# but cannot receive message that has expires (1 second, we wait for 2), and
|
73
102
|
# that message has been moved to the DLQ.
|
74
103
|
id1 = @queue.put 'first test message', :expires=>30, :delivery=>:repeated
|
75
104
|
id2 = @queue.put 'second test message', :expires=>1, :delivery=>:repeated
|
105
|
+
restart.call if restart
|
76
106
|
msg = @queue.get :id=>id1
|
77
107
|
assert msg, "Failed to retrieve message that did not expire"
|
78
108
|
sleep 2
|
@@ -84,6 +114,7 @@ class TestQueue < Test::Unit::TestCase
|
|
84
114
|
# Test that we can receive message more than once, but once we try more than
|
85
115
|
# max_deliveries, the message moves to the DLQ.
|
86
116
|
id1 = @queue.put 'test message', :max_retries=>1, :delivery=>:repeated
|
117
|
+
restart.call if restart
|
87
118
|
begin
|
88
119
|
@queue.get do |msg|
|
89
120
|
assert msg && msg.id == id1, "Block called without the message"
|
@@ -106,6 +137,7 @@ class TestQueue < Test::Unit::TestCase
|
|
106
137
|
|
107
138
|
# Test that message discarded when delivery mode is best_effort.
|
108
139
|
id1 = @queue.put 'test message', :max_retries=>0, :delivery=>:best_effort
|
140
|
+
restart.call if restart
|
109
141
|
begin
|
110
142
|
@queue.get do |msg|
|
111
143
|
assert msg && msg.id == id1, "Block called without the message"
|
@@ -119,6 +151,7 @@ class TestQueue < Test::Unit::TestCase
|
|
119
151
|
|
120
152
|
# Test that message is moved to DLQ when delivery mode is exactly_once.
|
121
153
|
id1 = @queue.put 'test message', :max_retries=>2, :delivery=>:once
|
154
|
+
restart.call if restart
|
122
155
|
begin
|
123
156
|
@queue.get do |msg|
|
124
157
|
assert msg && msg.id == id1, "Block called without the message"
|
@@ -134,10 +167,14 @@ class TestQueue < Test::Unit::TestCase
|
|
134
167
|
end
|
135
168
|
|
136
169
|
private
|
137
|
-
def clear
|
170
|
+
def clear complain
|
138
171
|
# Empty test queue and DLQ.
|
139
|
-
while @queue.get
|
140
|
-
|
172
|
+
while @queue.get
|
173
|
+
flunk "Found message in queue during clear" if complain
|
174
|
+
end
|
175
|
+
while @dlq.get
|
176
|
+
flunk "Found message in DLQ queue during clear" if complain
|
177
|
+
end
|
141
178
|
end
|
142
179
|
|
143
180
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: reliable-msg
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0.
|
7
|
-
date: 2005-11-
|
6
|
+
version: 1.0.1
|
7
|
+
date: 2005-11-11 00:00:00 -08:00
|
8
8
|
summary: Reliable messaging and persistent queues for building asynchronous applications in Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|