modern_times 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/README.rdoc +24 -12
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/examples/README +4 -0
  5. data/examples/jms.yml +9 -0
  6. data/examples/requestor/README +4 -2
  7. data/examples/requestor/manager.rb +3 -2
  8. data/examples/requestor/request.rb +5 -4
  9. data/examples/requestor/reverse_echo_worker.rb +3 -2
  10. data/examples/simple/README +7 -4
  11. data/examples/simple/bar_worker.rb +4 -1
  12. data/examples/simple/baz_worker.rb +4 -3
  13. data/examples/simple/manager.rb +3 -2
  14. data/examples/simple/publish.rb +6 -5
  15. data/lib/modern_times.rb +20 -2
  16. data/lib/modern_times/base/supervisor.rb +14 -21
  17. data/lib/modern_times/base/supervisor_mbean.rb +4 -6
  18. data/lib/modern_times/base/worker.rb +17 -26
  19. data/lib/modern_times/jms.rb +23 -0
  20. data/lib/modern_times/{hornetq/client.rb → jms/connection.rb} +19 -12
  21. data/lib/modern_times/jms/publisher.rb +91 -0
  22. data/lib/modern_times/jms/supervisor.rb +19 -0
  23. data/lib/modern_times/jms/supervisor_mbean.rb +11 -0
  24. data/lib/modern_times/jms/worker.rb +166 -0
  25. data/lib/modern_times/jms_requestor.rb +10 -0
  26. data/lib/modern_times/jms_requestor/request_handle.rb +33 -0
  27. data/lib/modern_times/jms_requestor/requestor.rb +45 -0
  28. data/lib/modern_times/jms_requestor/supervisor.rb +45 -0
  29. data/lib/modern_times/jms_requestor/supervisor_mbean.rb +21 -0
  30. data/lib/modern_times/jms_requestor/worker.rb +78 -0
  31. data/lib/modern_times/manager.rb +14 -9
  32. data/lib/modern_times/manager_mbean.rb +14 -7
  33. data/lib/modern_times/marshal_strategy.rb +47 -0
  34. data/lib/modern_times/marshal_strategy/bson.rb +31 -0
  35. data/lib/modern_times/marshal_strategy/json.rb +30 -0
  36. data/lib/modern_times/marshal_strategy/ruby.rb +20 -0
  37. data/lib/modern_times/marshal_strategy/string.rb +19 -0
  38. data/lib/modern_times/railsable.rb +17 -74
  39. data/test/base_test.rb +248 -0
  40. data/test/jms.yml +8 -0
  41. data/test/jms_requestor_test.rb +263 -0
  42. data/test/jms_test.rb +296 -0
  43. data/test/marshal_strategy_test.rb +39 -0
  44. metadata +49 -46
  45. data/examples/requestor/hornetq.yml +0 -14
  46. data/examples/simple/hornetq.yml +0 -14
  47. data/lib/modern_times/hornetq.rb +0 -11
  48. data/lib/modern_times/hornetq/marshal_strategy.rb +0 -3
  49. data/lib/modern_times/hornetq/marshal_strategy/json.rb +0 -17
  50. data/lib/modern_times/hornetq/marshal_strategy/ruby.rb +0 -17
  51. data/lib/modern_times/hornetq/marshal_strategy/string.rb +0 -17
  52. data/lib/modern_times/hornetq/publisher.rb +0 -65
  53. data/lib/modern_times/hornetq/supervisor.rb +0 -22
  54. data/lib/modern_times/hornetq/supervisor_mbean.rb +0 -12
  55. data/lib/modern_times/hornetq/worker.rb +0 -127
  56. data/lib/modern_times/hornetq_requestor.rb +0 -9
  57. data/lib/modern_times/hornetq_requestor/request_handle.rb +0 -49
  58. data/lib/modern_times/hornetq_requestor/requestor.rb +0 -48
  59. data/lib/modern_times/hornetq_requestor/worker.rb +0 -29
  60. data/lib/modern_times/thread.rb +0 -16
  61. data/test/base/worker_test.rb +0 -38
  62. data/test/messaging/worker_manager_test.rb +0 -58
  63. data/test/messaging/worker_test.rb +0 -58
  64. data/test/worker_manager_test.rb +0 -48
data/test/jms_test.rb ADDED
@@ -0,0 +1,296 @@
1
+ require 'modern_times'
2
+ require 'shoulda'
3
+ require 'test/unit'
4
+ require 'fileutils'
5
+ require 'erb'
6
+
7
+ # NOTE: This test requires a running ActiveMQ server
8
+
9
+ module WorkerHelper
10
+ @@workers = {}
11
+ @@mutex = Mutex.new
12
+ def initialize(opts={})
13
+ super
14
+ @@mutex.synchronize do
15
+ @@workers[self.class.name] ||= []
16
+ @@workers[self.class.name] << self
17
+ end
18
+ @hash = Hash.new(0)
19
+ end
20
+
21
+ def self.workers(worker_klass)
22
+ @@workers[worker_klass.name]
23
+ end
24
+
25
+ def self.reset_workers
26
+ @@workers = {}
27
+ end
28
+
29
+ def add_message(i)
30
+ @hash[i] += 1
31
+ end
32
+
33
+ def message_count
34
+ puts "hash=#{@hash.inspect}"
35
+ @hash.values.reduce(:+)
36
+ end
37
+
38
+ def messages
39
+ @hash.keys
40
+ end
41
+ end
42
+
43
+ module HashTest
44
+ module ModuleMethods
45
+ def create_obj(i)
46
+ {
47
+ 'foo' => 1,
48
+ 'bar' => {
49
+ 'message' => i,
50
+ 'dummy' => "Message #{i}"
51
+ },
52
+ # Only YAML will maintain symbols
53
+ :zulu => :rugger
54
+ }
55
+ end
56
+ end
57
+
58
+ def self.included(base)
59
+ base.extend(ModuleMethods)
60
+ end
61
+
62
+ def perform(obj)
63
+ add_message(obj['bar']['message'])
64
+ end
65
+ end
66
+
67
+ module BSONTest
68
+ extend ModernTimes::MarshalStrategy::BSON
69
+ include HashTest
70
+ end
71
+
72
+ module JSONTest
73
+ extend ModernTimes::MarshalStrategy::JSON
74
+ include HashTest
75
+ end
76
+
77
+ module RubyTest
78
+ extend ModernTimes::MarshalStrategy::Ruby
79
+
80
+ class MyClass
81
+ attr_reader :i
82
+ def initialize(i)
83
+ @i = i
84
+ end
85
+ end
86
+
87
+ def self.create_obj(i)
88
+ MyClass.new(i)
89
+ end
90
+
91
+ def perform(obj)
92
+ add_message(obj.i)
93
+ end
94
+ end
95
+
96
+ module StringTest
97
+ extend ModernTimes::MarshalStrategy::String
98
+
99
+ def self.create_obj(i)
100
+ "Message #{i}"
101
+ end
102
+
103
+ def perform(str)
104
+ if str =~ /^Message (\d+)$/
105
+ add_message($1.to_i)
106
+ else
107
+ raise "Unknown message: #{str}"
108
+ end
109
+ end
110
+ end
111
+
112
+ class DefaultWorker
113
+ include ModernTimes::JMS::Worker
114
+ include WorkerHelper
115
+ end
116
+
117
+ module Dummy
118
+ class DefaultWorker
119
+ include ModernTimes::JMS::Worker
120
+ include WorkerHelper
121
+ end
122
+ end
123
+
124
+ class SpecifiedQueueWorker
125
+ include ModernTimes::JMS::Worker
126
+ queue 'MyQueueName'
127
+ include WorkerHelper
128
+ end
129
+
130
+ class SpecifiedQueue2Worker
131
+ include ModernTimes::JMS::Worker
132
+ queue 'MyQueueName'
133
+ include WorkerHelper
134
+ end
135
+
136
+ class SpecifiedTopicWorker
137
+ include ModernTimes::JMS::Worker
138
+ virtual_topic 'MyTopicName'
139
+ include WorkerHelper
140
+ end
141
+
142
+ class SpecifiedTopic2Worker
143
+ include ModernTimes::JMS::Worker
144
+ virtual_topic 'MyTopicName'
145
+ include WorkerHelper
146
+ end
147
+
148
+ class JMSTest < Test::Unit::TestCase
149
+
150
+ @@server = JMX.simple_server
151
+ @@client = JMX.connect
152
+
153
+ def publish(marshal_module, range, options)
154
+ publisher = ModernTimes::JMS::Publisher.new(options.merge(:marshal => marshal_module))
155
+ puts "Publishing #{range} to #{publisher}"
156
+ range.each do |i|
157
+ obj = marshal_module.create_obj(i)
158
+ publisher.publish(obj)
159
+ end
160
+ end
161
+
162
+ def assert_worker(domain, worker_klasses, mbean_names, worker_count, range, min, max, instance_count)
163
+ puts "Checking #{worker_klasses.inspect}"
164
+ worker_klasses = [worker_klasses] unless worker_klasses.kind_of?(Array)
165
+ mbean_names = [mbean_names] unless mbean_names.kind_of?(Array)
166
+ workers = []
167
+ worker_klasses.each {|klass| workers.concat(WorkerHelper.workers(klass))}
168
+
169
+ assert_equal worker_count, workers.size
170
+ all_messages = []
171
+ workers.each do |worker|
172
+ msg_count = worker.message_count
173
+ assert msg_count >= min, "#{msg_count} is not between #{min} and #{max}"
174
+ assert msg_count <= max, "#{msg_count} is not between #{min} and #{max}"
175
+ # Make sure no duplicate messages
176
+ assert msg_count == worker.messages.size, "#{msg_count} is not == #{worker.messages.size}"
177
+ all_messages.concat(worker.messages)
178
+ end
179
+ all_messages.sort!
180
+ assert_equal all_messages, (range.to_a*instance_count).sort
181
+
182
+ if domain
183
+ total_count = 0
184
+ mbean_names.each do |mbean_name|
185
+ bean = @@client[ModernTimes.supervisor_mbean_object_name(domain, mbean_name)]
186
+ bean.message_counts.each do |msg_count|
187
+ total_count += msg_count
188
+ assert msg_count >= min, "#{msg_count} is not between #{min} and #{max}"
189
+ assert msg_count <= max, "#{msg_count} is not between #{min} and #{max}"
190
+ end
191
+ end
192
+ assert_equal all_messages.size, total_count
193
+ end
194
+ end
195
+
196
+ context 'jms' do
197
+ setup do
198
+ config = YAML.load(ERB.new(File.read(File.join(File.dirname(__FILE__), 'jms.yml'))).result(binding))
199
+ ModernTimes::JMS::Connection.init(config)
200
+ end
201
+
202
+ teardown do
203
+ end
204
+
205
+ #[BSONTest, JSONTest, RubyTest, StringTest].each do |marshal_module|
206
+ [BSONTest, JSONTest, StringTest].each do |marshal_module|
207
+ marshal_module.name =~ /(.*)Test/
208
+ marshal_type = $1
209
+
210
+ context "marshaling with #{marshal_type}" do
211
+ setup do
212
+ @domain = "Uniquize_#{marshal_module.name}"
213
+ @manager = ModernTimes::Manager.new(:domain => @domain)
214
+ end
215
+
216
+ teardown do
217
+ if @manager
218
+ @manager.stop
219
+ @manager.join
220
+ end
221
+ end
222
+
223
+ should "operate on queues and topics" do
224
+ WorkerHelper.reset_workers
225
+ [DefaultWorker, Dummy::DefaultWorker, SpecifiedQueueWorker, SpecifiedQueue2Worker, SpecifiedTopicWorker, SpecifiedTopic2Worker].each do |worker_klass|
226
+ worker_klass.send(:include, marshal_module)
227
+ worker_klass.send(:marshal, marshal_module)
228
+ end
229
+ @manager.add(DefaultWorker, 3)
230
+ @manager.add(DefaultWorker, 2, :name => 'DefaultClone')
231
+ @manager.add(Dummy::DefaultWorker, 4)
232
+ @manager.add(SpecifiedQueueWorker, 3)
233
+ @manager.add(SpecifiedQueueWorker, 2, :name => 'SpecifiedQueueClone')
234
+ @manager.add(SpecifiedQueue2Worker, 2)
235
+ @manager.add(SpecifiedTopicWorker, 3)
236
+ @manager.add(SpecifiedTopicWorker, 2, :name => 'SpecifiedTopicClone')
237
+ @manager.add(SpecifiedTopic2Worker, 2)
238
+
239
+ sleep 1
240
+
241
+ publish(marshal_module, 100..199, :queue_name => 'Default')
242
+ publish(marshal_module, 200..299, :queue_name => 'Dummy_Default')
243
+ publish(marshal_module, 300..499, :queue_name => 'MyQueueName')
244
+ publish(marshal_module, 500..599, :virtual_topic_name => 'MyTopicName')
245
+
246
+ # Let the workers do their thing
247
+ sleep 5
248
+
249
+ # DefaultWorker should have 5 instances running with each worker handling between 10-30 messages in the range 100.199
250
+ assert_worker(@domain, DefaultWorker, ['Default', 'DefaultClone'], 5, 100..199, 10, 30, 1)
251
+ assert_worker(@domain, Dummy::DefaultWorker, 'Dummy_Default', 4, 200..299, 15, 35, 1)
252
+ assert_worker(@domain, [SpecifiedQueueWorker,SpecifiedQueue2Worker], ['SpecifiedQueue', 'SpecifiedQueueClone', 'SpecifiedQueue2'], 7, 300..499, 20, 40, 1)
253
+ assert_worker(@domain, SpecifiedTopicWorker, ['SpecifiedTopic', 'SpecifiedTopicClone'], 5, 500..599, 30, 60, 2)
254
+ assert_worker(@domain, SpecifiedTopic2Worker, 'SpecifiedTopic2', 2, 500..599, 35, 65, 1)
255
+ end
256
+ end
257
+ end
258
+
259
+ context 'dummy publishing' do
260
+ setup do
261
+ workers = [
262
+ DefaultWorker,
263
+ Dummy::DefaultWorker,
264
+ SpecifiedQueueWorker,
265
+ SpecifiedQueue2Worker,
266
+ SpecifiedTopicWorker,
267
+ SpecifiedTopic2Worker,
268
+ ]
269
+ workers.each do |worker_klass|
270
+ worker_klass.send(:include, RubyTest)
271
+ end
272
+ WorkerHelper.reset_workers
273
+ ModernTimes::JMS::Publisher.setup_dummy_publishing(workers)
274
+ end
275
+
276
+ teardown do
277
+ ModernTimes::JMS::Publisher.clear_dummy_publishing
278
+ end
279
+
280
+ should "directly call applicable workers" do
281
+ publish(RubyTest, 100..199, :queue_name => 'Default')
282
+ publish(RubyTest, 200..299, :queue_name => 'Dummy_Default')
283
+ publish(RubyTest, 300..499, :queue_name => 'MyQueueName')
284
+ publish(RubyTest, 500..599, :virtual_topic_name => 'MyTopicName')
285
+
286
+ # DefaultWorker should have 5 instances running with each worker handling between 10-30 messages in the range 100.199
287
+ assert_worker(nil, DefaultWorker, nil, 1, 100..199, 100, 100, 1)
288
+ assert_worker(nil, Dummy::DefaultWorker, nil, 1, 200..299, 100, 100, 1)
289
+ assert_worker(nil, SpecifiedQueueWorker, nil, 1, 300..499, 200, 200, 1)
290
+ assert_worker(nil, SpecifiedQueue2Worker, nil, 1, 300..499, 200, 200, 1)
291
+ assert_worker(nil, SpecifiedTopicWorker, nil, 1, 500..599, 100, 100, 1)
292
+ assert_worker(nil, SpecifiedTopic2Worker, nil, 1, 500..599, 100, 100, 1)
293
+ end
294
+ end
295
+ end
296
+ end
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'modern_times'
5
+
6
+ class Klass
7
+ def initialize(str)
8
+ @str = str
9
+ end
10
+ def hello
11
+ @str
12
+ end
13
+ end
14
+
15
+ class MarshalStrategyTest < Test::Unit::TestCase
16
+ context '' do
17
+ setup do
18
+ @bson = Object.new
19
+ @json = Object.new
20
+ @ruby = Object.new
21
+ @string = Object.new
22
+ @bson.extend ModernTimes::MarshalStrategy::BSON
23
+ @json.extend ModernTimes::MarshalStrategy::JSON
24
+ @ruby.extend ModernTimes::MarshalStrategy::Ruby
25
+ @string.extend ModernTimes::MarshalStrategy::String
26
+ end
27
+
28
+ should 'marshal and unmarshal correctly' do
29
+ hash = {'foo' => 42, 'bar' => 'zulu'}
30
+ str = 'abcdef1234'
31
+ obj = Klass.new('hello')
32
+ assert_equal hash, @bson.unmarshal(@bson.marshal(hash))
33
+ assert_equal hash, @json.unmarshal(@json.marshal(hash))
34
+ assert_equal hash, @ruby.unmarshal(@ruby.marshal(hash))
35
+ assert_equal str, @string.unmarshal(@string.marshal(str))
36
+ assert_equal obj.hello, @ruby.unmarshal(@ruby.marshal(obj)).hello
37
+ end
38
+ end
39
+ end
metadata CHANGED
@@ -1,8 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modern_times
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.1.2
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
6
10
  platform: ruby
7
11
  authors:
8
12
  - Brad Pardee
@@ -11,42 +15,36 @@ autorequire:
11
15
  bindir: bin
12
16
  cert_chain: []
13
17
 
14
- date: 2011-03-24 00:00:00 -04:00
18
+ date: 2011-04-22 00:00:00 -04:00
15
19
  default_executable:
16
20
  dependencies:
17
21
  - !ruby/object:Gem::Dependency
18
- name: jruby-hornetq
22
+ name: jruby-jms
19
23
  prerelease: false
20
24
  requirement: &id001 !ruby/object:Gem::Requirement
21
- none: false
22
25
  requirements:
23
26
  - - ">="
24
27
  - !ruby/object:Gem::Version
25
- version: 0.3.3
28
+ segments:
29
+ - 0
30
+ - 11
31
+ - 0
32
+ version: 0.11.0
26
33
  type: :runtime
27
34
  version_requirements: *id001
28
35
  - !ruby/object:Gem::Dependency
29
36
  name: jmx
30
37
  prerelease: false
31
38
  requirement: &id002 !ruby/object:Gem::Requirement
32
- none: false
33
39
  requirements:
34
40
  - - ">="
35
41
  - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ - 6
36
45
  version: "0.6"
37
46
  type: :runtime
38
47
  version_requirements: *id002
39
- - !ruby/object:Gem::Dependency
40
- name: json
41
- prerelease: false
42
- requirement: &id003 !ruby/object:Gem::Requirement
43
- none: false
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: "0"
48
- type: :runtime
49
- version_requirements: *id003
50
48
  description: Generic asynchronous task library
51
49
  email:
52
50
  - bradpardee@gmail.com
@@ -63,9 +61,10 @@ files:
63
61
  - README.rdoc
64
62
  - Rakefile
65
63
  - VERSION
64
+ - examples/README
65
+ - examples/jms.yml
66
66
  - examples/requestor/.gitignore
67
67
  - examples/requestor/README
68
- - examples/requestor/hornetq.yml
69
68
  - examples/requestor/manager.rb
70
69
  - examples/requestor/request.rb
71
70
  - examples/requestor/reverse_echo_worker.rb
@@ -73,7 +72,6 @@ files:
73
72
  - examples/simple/README
74
73
  - examples/simple/bar_worker.rb
75
74
  - examples/simple/baz_worker.rb
76
- - examples/simple/hornetq.yml
77
75
  - examples/simple/manager.rb
78
76
  - examples/simple/publish.rb
79
77
  - lib/modern_times.rb
@@ -82,29 +80,32 @@ files:
82
80
  - lib/modern_times/base/supervisor_mbean.rb
83
81
  - lib/modern_times/base/worker.rb
84
82
  - lib/modern_times/exception.rb
85
- - lib/modern_times/hornetq.rb
86
- - lib/modern_times/hornetq/client.rb
87
- - lib/modern_times/hornetq/marshal_strategy.rb
88
- - lib/modern_times/hornetq/marshal_strategy/json.rb
89
- - lib/modern_times/hornetq/marshal_strategy/ruby.rb
90
- - lib/modern_times/hornetq/marshal_strategy/string.rb
91
- - lib/modern_times/hornetq/publisher.rb
92
- - lib/modern_times/hornetq/supervisor.rb
93
- - lib/modern_times/hornetq/supervisor_mbean.rb
94
- - lib/modern_times/hornetq/worker.rb
95
- - lib/modern_times/hornetq_requestor.rb
96
- - lib/modern_times/hornetq_requestor/request_handle.rb
97
- - lib/modern_times/hornetq_requestor/requestor.rb
98
- - lib/modern_times/hornetq_requestor/worker.rb
83
+ - lib/modern_times/jms.rb
84
+ - lib/modern_times/jms/connection.rb
85
+ - lib/modern_times/jms/publisher.rb
86
+ - lib/modern_times/jms/supervisor.rb
87
+ - lib/modern_times/jms/supervisor_mbean.rb
88
+ - lib/modern_times/jms/worker.rb
89
+ - lib/modern_times/jms_requestor.rb
90
+ - lib/modern_times/jms_requestor/request_handle.rb
91
+ - lib/modern_times/jms_requestor/requestor.rb
92
+ - lib/modern_times/jms_requestor/supervisor.rb
93
+ - lib/modern_times/jms_requestor/supervisor_mbean.rb
94
+ - lib/modern_times/jms_requestor/worker.rb
99
95
  - lib/modern_times/loggable.rb
100
96
  - lib/modern_times/manager.rb
101
97
  - lib/modern_times/manager_mbean.rb
98
+ - lib/modern_times/marshal_strategy.rb
99
+ - lib/modern_times/marshal_strategy/bson.rb
100
+ - lib/modern_times/marshal_strategy/json.rb
101
+ - lib/modern_times/marshal_strategy/ruby.rb
102
+ - lib/modern_times/marshal_strategy/string.rb
102
103
  - lib/modern_times/railsable.rb
103
- - lib/modern_times/thread.rb
104
- - test/base/worker_test.rb
105
- - test/worker_manager_test.rb
106
- - test/messaging/worker_manager_test.rb
107
- - test/messaging/worker_test.rb
104
+ - test/base_test.rb
105
+ - test/jms.yml
106
+ - test/jms_requestor_test.rb
107
+ - test/jms_test.rb
108
+ - test/marshal_strategy_test.rb
108
109
  has_rdoc: true
109
110
  homepage: http://github.com/ClarityServices/modern_times
110
111
  licenses: []
@@ -115,21 +116,23 @@ rdoc_options: []
115
116
  require_paths:
116
117
  - lib
117
118
  required_ruby_version: !ruby/object:Gem::Requirement
118
- none: false
119
119
  requirements:
120
120
  - - ">="
121
121
  - !ruby/object:Gem::Version
122
+ segments:
123
+ - 0
122
124
  version: "0"
123
125
  required_rubygems_version: !ruby/object:Gem::Requirement
124
- none: false
125
126
  requirements:
126
127
  - - ">="
127
128
  - !ruby/object:Gem::Version
129
+ segments:
130
+ - 0
128
131
  version: "0"
129
132
  requirements: []
130
133
 
131
134
  rubyforge_project:
132
- rubygems_version: 1.5.1
135
+ rubygems_version: 1.3.6
133
136
  signing_key:
134
137
  specification_version: 3
135
138
  summary: Asynchronous task library
@@ -141,7 +144,7 @@ test_files:
141
144
  - examples/simple/baz_worker.rb
142
145
  - examples/simple/manager.rb
143
146
  - examples/simple/publish.rb
144
- - test/base/worker_test.rb
145
- - test/messaging/worker_manager_test.rb
146
- - test/messaging/worker_test.rb
147
- - test/worker_manager_test.rb
147
+ - test/base_test.rb
148
+ - test/jms_requestor_test.rb
149
+ - test/jms_test.rb
150
+ - test/marshal_strategy_test.rb