modern_times 0.2.6 → 0.2.7
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/VERSION +1 -1
- data/examples/consumer/consumer.rb +24 -0
- data/lib/modern_times/jms/consumer.rb +76 -0
- data/lib/modern_times/jms/publisher.rb +13 -2
- data/lib/modern_times/jms.rb +1 -0
- data/lib/modern_times/jms_requestor/request_handle.rb +4 -4
- data/lib/modern_times/jms_requestor/requestor.rb +2 -2
- data/lib/modern_times/manager.rb +13 -5
- data/lib/modern_times/railsable.rb +14 -4
- metadata +4 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.7
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Allow examples to be run in-place without requiring a gem install
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'erb'
|
6
|
+
require 'modern_times'
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
if ARGV.size < 2
|
10
|
+
$stderr.puts "Usage: {$0} <message> <id>"
|
11
|
+
end
|
12
|
+
|
13
|
+
#ModernTimes::JMS::Publisher.setup_dummy_publishing([])
|
14
|
+
#ModernTimes::JMS::Consumer.setup_dummy_receiving
|
15
|
+
|
16
|
+
config = YAML.load(ERB.new(File.read(File.join(File.dirname(__FILE__), '..', 'jms.yml'))).result(binding))
|
17
|
+
ModernTimes::JMS::Connection.init(config)
|
18
|
+
publisher = ModernTimes::JMS::Publisher.new(:queue_name => 'Foo', :marshal => :string)
|
19
|
+
consumer = ModernTimes::JMS::Consumer.new(:queue_name => 'Foo', :marshal => :string)
|
20
|
+
|
21
|
+
publisher.publish(ARGV[0], :jms_correlation_id => ARGV[1])
|
22
|
+
msg = consumer.receive(:jms_correlation_id => ARGV[1], :timeout => 30000)
|
23
|
+
#msg = consumer.receive(:timeout => 1000)
|
24
|
+
puts "msg=#{msg}"
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'jms'
|
2
|
+
|
3
|
+
# Protocol independent class to handle Publishing
|
4
|
+
module ModernTimes
|
5
|
+
module JMS
|
6
|
+
class Consumer
|
7
|
+
attr_reader :consumer_options, :persistent, :marshaler
|
8
|
+
|
9
|
+
# Parameters:
|
10
|
+
# One of the following must be specified
|
11
|
+
# :queue_name => String: Name of the Queue to publish to
|
12
|
+
# :topic_name => String: Name of the Topic to publish to
|
13
|
+
# :virtual_topic_name => String: Name of the Virtual Topic to publish to
|
14
|
+
# (ActiveMQ only, see http://activemq.apache.org/virtual-destinations.html
|
15
|
+
# :destination=> Explicit javax::Jms::Destination to use
|
16
|
+
# Optional:
|
17
|
+
# :persistent => true or false (defaults to false)
|
18
|
+
# :marshal => Symbol: One of :ruby, :string, or :json
|
19
|
+
# => Module: Module that defines marshal and unmarshal method
|
20
|
+
def initialize(options)
|
21
|
+
consumer_keys = [:queue_name, :topic_name, :virtual_topic_name, :destination]
|
22
|
+
@consumer_options = options.reject {|k,v| !consumer_keys.include?(k)}
|
23
|
+
raise "One of #{consumer_keys.join(',')} must be given in #{self.class.name}" if @consumer_options.empty?
|
24
|
+
|
25
|
+
# Save our @consumer_options for destination comparison when doing dummy_publish,
|
26
|
+
# but create the real options by translating virtual_topic_name to a real topic_name.
|
27
|
+
@real_consumer_options = @consumer_options.dup
|
28
|
+
virtual_topic_name = @real_consumer_options.delete(:virtual_topic_name)
|
29
|
+
@real_consumer_options[:topic_name] = "VirtualTopic.#{virtual_topic_name}" if virtual_topic_name
|
30
|
+
@marshaler = ModernTimes::MarshalStrategy.find(options[:marshal])
|
31
|
+
end
|
32
|
+
|
33
|
+
# Publish the given object to the address.
|
34
|
+
def receive(options={})
|
35
|
+
options = @real_consumer_options.merge(options)
|
36
|
+
correlation_id = options.delete(:jms_correlation_id)
|
37
|
+
options[:selector] = "JMSCorrelationID = '#{correlation_id}'" if correlation_id && !options[:selector]
|
38
|
+
timeout = options.delete(:timeout) || 0
|
39
|
+
obj = nil
|
40
|
+
|
41
|
+
Connection.session_pool.consumer(options) do |session, consumer|
|
42
|
+
message = consumer.get(:timeout => timeout)
|
43
|
+
obj = @marshaler.unmarshal(message.data) if message
|
44
|
+
end
|
45
|
+
return obj
|
46
|
+
end
|
47
|
+
|
48
|
+
# For non-configured Rails projects, The above publish method will be overridden to
|
49
|
+
# call this publish method instead which calls all the JMS workers that
|
50
|
+
# operate on the given address.
|
51
|
+
def dummy_receive(options={})
|
52
|
+
if correlation_id = options.delete(:jms_correlation_id)
|
53
|
+
return Publisher.dummy_cache(correlation_id)
|
54
|
+
else
|
55
|
+
# TODO: Pop off if no correlation id given
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
"#{self.class.name}:#{@real_consumer_options.inspect}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.setup_dummy_receiving
|
64
|
+
alias_method :real_receive, :receive
|
65
|
+
alias_method :receive, :dummy_receive
|
66
|
+
end
|
67
|
+
|
68
|
+
# For testing
|
69
|
+
def self.clear_dummy_receiving
|
70
|
+
alias_method :dummy_receive, :receive
|
71
|
+
alias_method :receive, :real_receive
|
72
|
+
#remove_method :real_receive
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -47,19 +47,24 @@ module ModernTimes
|
|
47
47
|
#producer.send_with_retry(message)
|
48
48
|
producer.send(message)
|
49
49
|
end
|
50
|
-
return message
|
50
|
+
return message.jms_message_id
|
51
51
|
end
|
52
52
|
|
53
53
|
# For non-configured Rails projects, The above publish method will be overridden to
|
54
54
|
# call this publish method instead which calls all the JMS workers that
|
55
55
|
# operate on the given address.
|
56
|
-
def dummy_publish(object)
|
56
|
+
def dummy_publish(object, props={})
|
57
|
+
@@message_id += 1
|
57
58
|
@@worker_instances.each do |worker|
|
58
59
|
if worker.kind_of?(Worker) && ModernTimes::JMS.same_destination?(@producer_options, worker.class.destination_options)
|
59
60
|
ModernTimes.logger.debug "Dummy publishing #{object} to #{worker}"
|
60
61
|
worker.perform(object)
|
61
62
|
end
|
62
63
|
end
|
64
|
+
if correlation_id = props[:jms_correlation_id]
|
65
|
+
@@dummy_cache[correlation_id] = object
|
66
|
+
end
|
67
|
+
return @@message_id
|
63
68
|
end
|
64
69
|
|
65
70
|
def to_s
|
@@ -67,6 +72,8 @@ module ModernTimes
|
|
67
72
|
end
|
68
73
|
|
69
74
|
def self.setup_dummy_publishing(workers)
|
75
|
+
@@message_id = 0
|
76
|
+
@@dummy_cache = {}
|
70
77
|
@@worker_instances = workers.map {|worker| worker.new}
|
71
78
|
alias_method :real_publish, :publish
|
72
79
|
alias_method :publish, :dummy_publish
|
@@ -78,6 +85,10 @@ module ModernTimes
|
|
78
85
|
alias_method :publish, :real_publish
|
79
86
|
#remove_method :real_publish
|
80
87
|
end
|
88
|
+
|
89
|
+
def self.dummy_cache(correlation_id)
|
90
|
+
@@dummy_cache.delete(correlation_id)
|
91
|
+
end
|
81
92
|
end
|
82
93
|
end
|
83
94
|
end
|
data/lib/modern_times/jms.rb
CHANGED
@@ -4,10 +4,10 @@ require 'yaml'
|
|
4
4
|
module ModernTimes
|
5
5
|
module JMSRequestor
|
6
6
|
class RequestHandle
|
7
|
-
def initialize(requestor,
|
7
|
+
def initialize(requestor, jms_message_id, start, timeout, &reconstruct_block)
|
8
8
|
@requestor = requestor
|
9
9
|
@reply_queue = requestor.reply_queue
|
10
|
-
@
|
10
|
+
@jms_message_id = jms_message_id
|
11
11
|
@start = start
|
12
12
|
@timeout = timeout
|
13
13
|
@reconstruct_block = reconstruct_block
|
@@ -15,7 +15,7 @@ module ModernTimes
|
|
15
15
|
|
16
16
|
def read_response
|
17
17
|
response = nil
|
18
|
-
opts = { :destination => @reply_queue, :selector => "JMSCorrelationID = '#{@
|
18
|
+
opts = { :destination => @reply_queue, :selector => "JMSCorrelationID = '#{@jms_message_id}'" }
|
19
19
|
#opts = { :destination => @reply_queue }
|
20
20
|
#opts = {:queue_name => 'foobarzulu'}
|
21
21
|
ModernTimes::JMS::Connection.session_pool.consumer(opts) do |session, consumer|
|
@@ -27,7 +27,7 @@ module ModernTimes
|
|
27
27
|
response = consumer.receive(100)
|
28
28
|
end
|
29
29
|
end
|
30
|
-
raise Timeout::Error, "Timeout waiting for for response from message #{@
|
30
|
+
raise Timeout::Error, "Timeout waiting for for response from message #{@jms_message_id} on queue #{@reply_queue}" unless response
|
31
31
|
if error_yaml = response['Exception']
|
32
32
|
raise ModernTimes::RemoteException.from_hash(YAML.load(error_yaml))
|
33
33
|
end
|
@@ -16,8 +16,8 @@ module ModernTimes
|
|
16
16
|
|
17
17
|
def request(object, timeout, &reconstruct_block)
|
18
18
|
start = Time.now
|
19
|
-
|
20
|
-
return RequestHandle.new(self,
|
19
|
+
jms_message_id = publish(object, :jms_reply_to => @reply_queue)
|
20
|
+
return RequestHandle.new(self, jms_message_id, start, timeout, &reconstruct_block)
|
21
21
|
end
|
22
22
|
|
23
23
|
# For non-configured Rails projects, The above request method will be overridden to
|
data/lib/modern_times/manager.rb
CHANGED
@@ -11,11 +11,17 @@ module ModernTimes
|
|
11
11
|
@config = config
|
12
12
|
@domain = config[:domain] || ModernTimes::DEFAULT_DOMAIN
|
13
13
|
@supervisors = []
|
14
|
-
@jmx_server = JMX::MBeanServer.new
|
15
|
-
bean = ManagerMBean.new(@domain, self)
|
16
|
-
@jmx_server.register_mbean(bean, ModernTimes.manager_mbean_object_name(@domain))
|
17
14
|
self.persist_file = config[:persist_file]
|
18
15
|
self.worker_file = config[:worker_file]
|
16
|
+
@allowed_workers = config[:allowed_workers]
|
17
|
+
stop_on_signal if config[:stop_on_signal]
|
18
|
+
@dummy_host = config[:dummy_host]
|
19
|
+
# Unless specifically unconfigured (i.e., Rails.env == test), then enable jmx
|
20
|
+
if config[:jmx] != false
|
21
|
+
@jmx_server = JMX::MBeanServer.new
|
22
|
+
bean = ManagerMBean.new(@domain, self)
|
23
|
+
@jmx_server.register_mbean(bean, ModernTimes.manager_mbean_object_name(@domain))
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
def add(worker_klass, num_workers, worker_options={})
|
@@ -32,10 +38,12 @@ module ModernTimes
|
|
32
38
|
end
|
33
39
|
supervisor = worker_klass.create_supervisor(self, worker_options)
|
34
40
|
raise "A supervisor with name #{supervisor.name} already exists" if find_supervisor(supervisor.name)
|
35
|
-
mbean = supervisor.create_mbean(@domain)
|
36
41
|
@supervisors << supervisor
|
37
42
|
supervisor.worker_count = num_workers
|
38
|
-
@jmx_server
|
43
|
+
if @jmx_server
|
44
|
+
mbean = supervisor.create_mbean(@domain)
|
45
|
+
@jmx_server.register_mbean(mbean, "#{@domain}:worker=#{supervisor.name},type=Worker")
|
46
|
+
end
|
39
47
|
ModernTimes.logger.info "Started #{worker_klass.name} named #{supervisor.name} with #{num_workers} workers"
|
40
48
|
rescue Exception => e
|
41
49
|
ModernTimes.logger.error "Exception trying to add #{worker_klass}: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
|
@@ -47,20 +47,30 @@ module ModernTimes
|
|
47
47
|
Rails.logger.info "Messaging disabled"
|
48
48
|
@is_jms_enabled = false
|
49
49
|
ModernTimes::JMS::Publisher.setup_dummy_publishing(rails_workers)
|
50
|
+
ModernTimes::JMS::Consumer.setup_dummy_receiving
|
50
51
|
ModernTimes::JMSRequestor::Requestor.setup_dummy_requesting(rails_workers)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
|
-
def create_rails_manager
|
55
|
+
def create_rails_manager(manager_config={})
|
55
56
|
# Take advantage of nil and false values for boolean
|
56
57
|
raise 'init_rails has not been called, modify your config/environment.rb to include this call' if @is_jms_enabled.nil?
|
57
58
|
raise 'Messaging is not enabled, modify your config/jms.yml file' unless @is_jms_enabled
|
58
|
-
|
59
|
+
default_config = {
|
60
|
+
:persist_file => File.join(Rails.root, "log", "modern_times.persist"),
|
61
|
+
:worker_file => File.join(Rails.root, "config", "workers.yml"),
|
62
|
+
:jmx => Rails.env != 'test',
|
63
|
+
:stop_on_signal => true,
|
64
|
+
:dummy_host => Rails.env,
|
65
|
+
:allowed_workers => rails_workers,
|
66
|
+
}
|
67
|
+
|
68
|
+
manager = ModernTimes::Manager.new(default_config.merge(manager_config))
|
59
69
|
manager.stop_on_signal
|
60
70
|
manager.allowed_workers = rails_workers
|
61
|
-
manager.persist_file =
|
71
|
+
manager.persist_file = manager_config[:persist_file] || File.join(Rails.root, "log", "modern_times.persist")
|
62
72
|
manager.dummy_host = Rails.env
|
63
|
-
manager.worker_file =
|
73
|
+
manager.worker_file = manager_config[:worker_file] || File.join(Rails.root, "config", "workers.yml")
|
64
74
|
return manager
|
65
75
|
end
|
66
76
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: modern_times
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.7
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Brad Pardee
|
@@ -53,6 +53,7 @@ files:
|
|
53
53
|
- Rakefile
|
54
54
|
- VERSION
|
55
55
|
- examples/README
|
56
|
+
- examples/consumer/consumer.rb
|
56
57
|
- examples/jms.yml
|
57
58
|
- examples/requestor/.gitignore
|
58
59
|
- examples/requestor/README
|
@@ -72,6 +73,7 @@ files:
|
|
72
73
|
- lib/modern_times/base/worker.rb
|
73
74
|
- lib/modern_times/jms.rb
|
74
75
|
- lib/modern_times/jms/connection.rb
|
76
|
+
- lib/modern_times/jms/consumer.rb
|
75
77
|
- lib/modern_times/jms/publisher.rb
|
76
78
|
- lib/modern_times/jms/supervisor.rb
|
77
79
|
- lib/modern_times/jms/supervisor_mbean.rb
|
@@ -130,6 +132,7 @@ signing_key:
|
|
130
132
|
specification_version: 3
|
131
133
|
summary: Asynchronous task library
|
132
134
|
test_files:
|
135
|
+
- examples/consumer/consumer.rb
|
133
136
|
- examples/exception_test/bar_worker.rb
|
134
137
|
- examples/exception_test/base_worker.rb
|
135
138
|
- examples/exception_test/manager.rb
|