modern_times 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.6
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
@@ -1,4 +1,5 @@
1
1
  require 'modern_times/jms/connection'
2
+ require 'modern_times/jms/consumer'
2
3
  require 'modern_times/jms/publisher'
3
4
  require 'modern_times/jms/supervisor_mbean'
4
5
  require 'modern_times/jms/supervisor'
@@ -4,10 +4,10 @@ require 'yaml'
4
4
  module ModernTimes
5
5
  module JMSRequestor
6
6
  class RequestHandle
7
- def initialize(requestor, message, start, timeout, &reconstruct_block)
7
+ def initialize(requestor, jms_message_id, start, timeout, &reconstruct_block)
8
8
  @requestor = requestor
9
9
  @reply_queue = requestor.reply_queue
10
- @message = message
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 = '#{@message.jms_message_id}'" }
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 #{@message.jms_message_id} on queue #{@reply_queue}" unless response
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
- message = publish(object, :jms_reply_to => @reply_queue)
20
- return RequestHandle.new(self, message, start, timeout, &reconstruct_block)
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
@@ -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.register_mbean(mbean, "#{@domain}:worker=#{supervisor.name},type=Worker")
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
- manager = ModernTimes::Manager.new
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 = @config[:persist_file] || File.join(Rails.root, "log", "modern_times.persist")
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 = @config[:worker_file] || File.join(Rails.root, "config", "workers.yml")
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.6
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