qwirk 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -14
- data/lib/qwirk.rb +26 -17
- data/lib/qwirk/adapter.rb +3 -45
- data/lib/qwirk/adapter/base.rb +2 -0
- data/lib/qwirk/adapter/base/expanding_worker_config.rb +133 -0
- data/lib/qwirk/adapter/base/worker_config.rb +104 -0
- data/lib/qwirk/adapter/in_memory.rb +13 -0
- data/lib/qwirk/{queue_adapter/in_mem → adapter/in_memory}/factory.rb +2 -2
- data/lib/qwirk/{queue_adapter/in_mem → adapter/in_memory}/publisher.rb +4 -4
- data/lib/qwirk/{queue_adapter/in_mem → adapter/in_memory}/queue.rb +3 -2
- data/lib/qwirk/{queue_adapter/in_mem → adapter/in_memory}/reply_queue.rb +3 -2
- data/lib/qwirk/{queue_adapter/in_mem → adapter/in_memory}/topic.rb +2 -2
- data/lib/qwirk/{queue_adapter/in_mem → adapter/in_memory}/worker.rb +6 -8
- data/lib/qwirk/adapter/in_memory/worker_config.rb +50 -0
- data/lib/qwirk/adapter/inline.rb +9 -0
- data/lib/qwirk/adapter/inline/publisher.rb +86 -0
- data/lib/qwirk/adapter/inline/worker.rb +55 -0
- data/lib/qwirk/adapter/inline/worker_config.rb +30 -0
- data/lib/qwirk/adapter_factory.rb +48 -0
- data/lib/qwirk/base_worker.rb +18 -28
- data/lib/qwirk/batch/file_worker.rb +4 -4
- data/lib/qwirk/manager.rb +11 -8
- data/lib/qwirk/marshal_strategy/none.rb +1 -1
- data/lib/qwirk/publish_handle.rb +22 -11
- data/lib/qwirk/publisher.rb +9 -9
- data/lib/qwirk/{request_worker.rb → reply_worker.rb} +3 -3
- data/lib/qwirk/worker.rb +27 -29
- data/test/jms_fail_test.rb +11 -11
- data/test/jms_requestor_block_test.rb +12 -12
- data/test/jms_requestor_test.rb +8 -8
- data/test/jms_test.rb +10 -10
- metadata +104 -185
- data/examples/README +0 -1
- data/examples/activemq.xml +0 -84
- data/examples/advanced_requestor/README.md +0 -15
- data/examples/advanced_requestor/base_request_worker.rb +0 -18
- data/examples/advanced_requestor/char_count_worker.rb +0 -16
- data/examples/advanced_requestor/config.ru +0 -24
- data/examples/advanced_requestor/exception_raiser_worker.rb +0 -17
- data/examples/advanced_requestor/length_worker.rb +0 -14
- data/examples/advanced_requestor/print_worker.rb +0 -14
- data/examples/advanced_requestor/publisher.rb +0 -49
- data/examples/advanced_requestor/qwirk.yml +0 -16
- data/examples/advanced_requestor/reverse_worker.rb +0 -14
- data/examples/advanced_requestor/triple_worker.rb +0 -14
- data/examples/batch/my_batch_worker.rb +0 -30
- data/examples/batch/my_line_worker.rb +0 -8
- data/examples/qwirk.yml +0 -20
- data/examples/requestor/README.md +0 -13
- data/examples/requestor/config.ru +0 -13
- data/examples/requestor/qwirk_persist.yml +0 -5
- data/examples/requestor/requestor.rb +0 -68
- data/examples/requestor/reverse_echo_worker.rb +0 -15
- data/examples/setup.rb +0 -13
- data/examples/shared/README.md +0 -24
- data/examples/shared/config.ru +0 -13
- data/examples/shared/publisher.rb +0 -49
- data/examples/shared/qwirk_persist.yml +0 -5
- data/examples/shared/shared_worker.rb +0 -16
- data/examples/simple/README +0 -53
- data/examples/simple/bar_worker.rb +0 -10
- data/examples/simple/baz_worker.rb +0 -10
- data/examples/simple/config.ru +0 -14
- data/examples/simple/publisher.rb +0 -49
- data/examples/simple/qwirk_persist.yml +0 -4
- data/examples/simple/tmp/kahadb/db-1.log +0 -0
- data/examples/simple/tmp/kahadb/db.data +0 -0
- data/examples/simple/tmp/kahadb/db.redo +0 -0
- data/examples/task/README +0 -47
- data/examples/task/config.ru +0 -14
- data/examples/task/foo_worker.rb +0 -10
- data/examples/task/messages.out +0 -1000
- data/examples/task/publisher.rb +0 -25
- data/examples/task/qwirk_persist.yml +0 -5
- data/examples/task/task.rb +0 -36
- data/lib/qwirk/queue_adapter.rb +0 -3
- data/lib/qwirk/queue_adapter/active_mq.rb +0 -13
- data/lib/qwirk/queue_adapter/active_mq/publisher.rb +0 -12
- data/lib/qwirk/queue_adapter/active_mq/worker_config.rb +0 -16
- data/lib/qwirk/queue_adapter/in_mem.rb +0 -7
- data/lib/qwirk/queue_adapter/in_mem/worker_config.rb +0 -59
- data/lib/qwirk/queue_adapter/jms.rb +0 -50
- data/lib/qwirk/queue_adapter/jms/connection.rb +0 -42
- data/lib/qwirk/queue_adapter/jms/consumer.rb +0 -37
- data/lib/qwirk/queue_adapter/jms/publisher.rb +0 -126
- data/lib/qwirk/queue_adapter/jms/worker.rb +0 -89
- data/lib/qwirk/queue_adapter/jms/worker_config.rb +0 -38
- data/lib/qwirk/version.rb +0 -3
- data/lib/qwirk/worker_config.rb +0 -187
@@ -1,7 +1,7 @@
|
|
1
1
|
module Qwirk
|
2
2
|
module Batch
|
3
3
|
|
4
|
-
# Batch worker which reads records from files and queues them up for a separate worker (Qwirk::
|
4
|
+
# Batch worker which reads records from files and queues them up for a separate worker (Qwirk::Adapter::JMS::ReplyWorker) to process.
|
5
5
|
# For instance, a worker of this type might look as follows:
|
6
6
|
# class MyBatchWorker
|
7
7
|
# include Qwirk::Batch::FileWorker
|
@@ -204,18 +204,18 @@ module Qwirk
|
|
204
204
|
#######
|
205
205
|
|
206
206
|
def reply_event_loop
|
207
|
-
@reply_session = Qwirk::
|
207
|
+
@reply_session = Qwirk::Adapter::JMS::Connection.create_session
|
208
208
|
@consumer = @reply_session.consumer(:queue_name => @queue_name)
|
209
209
|
@reply_session.start
|
210
210
|
|
211
211
|
while !@stopped && message = @consumer.receive
|
212
212
|
@message_mutex.synchronize do
|
213
|
-
obj = Qwirk::
|
213
|
+
obj = Qwirk::Adapter::JMS.parse_response(message)
|
214
214
|
process_response(obj)
|
215
215
|
message.acknowledge
|
216
216
|
end
|
217
217
|
# TODO: @time_track now in WorkerConfig
|
218
|
-
#Qwirk.logger.info {"#{self}::on_message (#{('%.1f' % (@time_track.last_time*1000.0))}ms)"} if Qwirk::
|
218
|
+
#Qwirk.logger.info {"#{self}::on_message (#{('%.1f' % (@time_track.last_time*1000.0))}ms)"} if Qwirk::Adapter::JMS::Connection.log_times?
|
219
219
|
end
|
220
220
|
@status = 'Exited'
|
221
221
|
Qwirk.logger.info "#{self}: Exiting"
|
data/lib/qwirk/manager.rb
CHANGED
@@ -25,9 +25,9 @@ module Qwirk
|
|
25
25
|
# production, a set of workers could be defined under production or specific workers for each host name.
|
26
26
|
# persist_file - WorkerConfig attributes that are modified externally (via Rumx interface) will be stored in this file. Without this
|
27
27
|
# option, external config changes that are made will be lost when the Manager is restarted.
|
28
|
-
def initialize(
|
28
|
+
def initialize(adapter_factory, options={})
|
29
|
+
@adapter_factory = adapter_factory
|
29
30
|
options = @@default_options.merge(options)
|
30
|
-
#puts "creating qwirk manager with #{options.inspect}"
|
31
31
|
@stopped = false
|
32
32
|
@name = options[:name] || Qwirk::DEFAULT_NAME
|
33
33
|
@poll_time = 3.0
|
@@ -38,13 +38,13 @@ module Qwirk
|
|
38
38
|
@persist_options = (@persist_file && File.exist?(@persist_file)) ? YAML.load_file(@persist_file) : {}
|
39
39
|
|
40
40
|
BaseWorker.worker_classes.each do |worker_class|
|
41
|
-
worker_config_class
|
42
|
-
|
43
|
-
#
|
41
|
+
worker_class.each_config(adapter_factory.worker_config_class) do |config_name, extended_worker_config_class, default_options|
|
42
|
+
# Least priority is config default_options defined in the Worker class, then the workers.yml file,
|
43
|
+
# highest priority is persist_file (ad-hoc changes made manually)
|
44
44
|
options = {}
|
45
45
|
options = options.merge(@worker_options[config_name]) if @worker_options[config_name]
|
46
46
|
options = options.merge(@persist_options[config_name]) if @persist_options[config_name]
|
47
|
-
worker_config =
|
47
|
+
worker_config = extended_worker_config_class.new(adapter_factory, config_name, self, worker_class, default_options, options)
|
48
48
|
bean_add_child(config_name, worker_config)
|
49
49
|
@worker_configs << worker_config
|
50
50
|
end
|
@@ -54,6 +54,8 @@ module Qwirk
|
|
54
54
|
stop_on_signal if options[:stop_on_signal]
|
55
55
|
end
|
56
56
|
|
57
|
+
# Create a timer_thread to make periodic calls to the worker_configs in order to do such things as expand/contract
|
58
|
+
# workers, etc.
|
57
59
|
def start_timer_thread
|
58
60
|
# TODO: Optionize hard-coded values
|
59
61
|
@timer_thread = Thread.new do
|
@@ -86,12 +88,13 @@ module Qwirk
|
|
86
88
|
end
|
87
89
|
end
|
88
90
|
|
91
|
+
# Store off any options that are no longer set to default
|
89
92
|
def save_persist_state
|
90
93
|
return unless @persist_file
|
91
94
|
new_persist_options = {}
|
92
95
|
BaseWorker.worker_classes.each do |worker_class|
|
93
|
-
worker_class.each_config do |config_name,
|
94
|
-
static_options =
|
96
|
+
worker_class.each_config(@adapter_factory.worker_config_class) do |config_name, ignored_extended_worker_config_class, default_options|
|
97
|
+
static_options = default_options.merge(@worker_options[config_name] || {})
|
95
98
|
worker_config = self[config_name]
|
96
99
|
hash = {}
|
97
100
|
# Only store off the config values that are specifically different from default values or values set in the workers.yml file
|
data/lib/qwirk/publish_handle.rb
CHANGED
@@ -3,9 +3,14 @@ require 'timeout'
|
|
3
3
|
module Qwirk
|
4
4
|
class PublishHandle
|
5
5
|
def initialize(publisher, adapter_info, start)
|
6
|
-
@producer
|
6
|
+
@producer = publisher
|
7
7
|
@adapter_info = adapter_info
|
8
8
|
@start = start
|
9
|
+
@timeout = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def timeout?
|
13
|
+
@timeout
|
9
14
|
end
|
10
15
|
|
11
16
|
# Waits the given timeout for a response message on the queue.
|
@@ -54,13 +59,19 @@ module Qwirk
|
|
54
59
|
# Creates a block for reading the responses for a given message_id (adapter_info). The block will be passed an object
|
55
60
|
# that responds to timeout_read(timeout) with a [original_message_id, response_message, worker_name] tri or nil if no message is read.
|
56
61
|
# This is used in the RPC mechanism where a publish might wait for 1 or more workers to respond.
|
57
|
-
@producer.
|
62
|
+
@producer.impl.with_response(@adapter_info) do |consumer|
|
58
63
|
if block_given?
|
59
64
|
return read_multiple_response(consumer, timeout, &block)
|
60
65
|
else
|
61
|
-
|
62
|
-
|
63
|
-
|
66
|
+
tri = read_single_response(consumer, timeout)
|
67
|
+
if tri
|
68
|
+
response = tri[1]
|
69
|
+
raise response if response.kind_of?(Qwirk::RemoteException)
|
70
|
+
return response
|
71
|
+
else
|
72
|
+
@timeout = !tri
|
73
|
+
return nil
|
74
|
+
end
|
64
75
|
end
|
65
76
|
end
|
66
77
|
end
|
@@ -71,8 +82,7 @@ module Qwirk
|
|
71
82
|
|
72
83
|
def read_single_response(consumer, timeout)
|
73
84
|
leftover_timeout = @start + timeout - Time.now
|
74
|
-
|
75
|
-
return response
|
85
|
+
return consumer.timeout_read(leftover_timeout)
|
76
86
|
end
|
77
87
|
|
78
88
|
def read_multiple_response(consumer, timeout, &block)
|
@@ -80,15 +90,16 @@ module Qwirk
|
|
80
90
|
yield worker_response
|
81
91
|
|
82
92
|
until worker_response.done? do
|
83
|
-
|
84
|
-
if !
|
93
|
+
tri = read_single_response(consumer, timeout)
|
94
|
+
if !tri
|
85
95
|
worker_response.make_timeout_calls
|
86
96
|
return
|
87
97
|
end
|
98
|
+
ignored_message_id, response, worker_name = tri
|
88
99
|
if response.kind_of?(Qwirk::RemoteException)
|
89
|
-
worker_response.make_exception_call(
|
100
|
+
worker_response.make_exception_call(worker_name, response)
|
90
101
|
else
|
91
|
-
worker_response.make_message_call(
|
102
|
+
worker_response.make_message_call(worker_name, response)
|
92
103
|
end
|
93
104
|
end
|
94
105
|
end
|
data/lib/qwirk/publisher.rb
CHANGED
@@ -4,7 +4,7 @@ module Qwirk
|
|
4
4
|
include Rumx::Bean
|
5
5
|
|
6
6
|
#attr_reader :producer_options, :persistent, :reply_queue
|
7
|
-
attr_reader :response_options, :
|
7
|
+
attr_reader :response_options, :impl, :marshaler
|
8
8
|
|
9
9
|
bean_attr_reader :tasks, :hash, 'Hash of the latest tasks', :hash_type => :bean
|
10
10
|
|
@@ -19,7 +19,7 @@ module Qwirk
|
|
19
19
|
# :response => if true or a hash of response options, a temporary reply queue will be setup for handling responses
|
20
20
|
# :time_to_live => expiration time in ms for the response message(s) (JMS))
|
21
21
|
# :persistent => true or false for the response message(s), set to false if you don't want timed out messages ending up in the DLQ (defaults to true unless time_to_live is set)
|
22
|
-
def initialize(
|
22
|
+
def initialize(adapter_factory, options)
|
23
23
|
options = options.dup
|
24
24
|
@queue_name = options.delete(:queue_name)
|
25
25
|
@topic_name = options.delete(:topic_name)
|
@@ -29,17 +29,17 @@ module Qwirk
|
|
29
29
|
# response_options should only be a hash or the values true or false
|
30
30
|
@response_options = {} if @response_options && !@response_options.kind_of?(Hash)
|
31
31
|
|
32
|
-
@tasks
|
33
|
-
@
|
34
|
-
marshal_sym
|
35
|
-
@marshaler
|
32
|
+
@tasks = {}
|
33
|
+
@impl = adapter_factory.create_publisher_impl(@queue_name, @topic_name, options, @response_options)
|
34
|
+
marshal_sym = options[:marshal] || :ruby
|
35
|
+
@marshaler = Qwirk::MarshalStrategy.find(marshal_sym)
|
36
36
|
end
|
37
37
|
|
38
38
|
# Publish the given object to the address.
|
39
39
|
def publish(object, props={})
|
40
40
|
start = Time.now
|
41
41
|
marshaled_object = @marshaler.marshal(object)
|
42
|
-
adapter_info = @
|
42
|
+
adapter_info = @impl.publish(marshaled_object, @marshaler, nil, props)
|
43
43
|
return PublishHandle.new(self, adapter_info, start)
|
44
44
|
end
|
45
45
|
|
@@ -49,7 +49,7 @@ module Qwirk
|
|
49
49
|
# last message read. It should also respond to stop which will interrupt any receive calls causing it to return nil.
|
50
50
|
def create_producer_consumer_pair(task)
|
51
51
|
@tasks[task.task_id] = task
|
52
|
-
@
|
52
|
+
@impl.create_producer_consumer_pair(task.task_id, @marshaler)
|
53
53
|
end
|
54
54
|
|
55
55
|
def to_s
|
@@ -61,7 +61,7 @@ module Qwirk
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def create_fail_queue_consumer(fail_queue_name=nil)
|
64
|
-
fail_queue_name
|
64
|
+
fail_queue_name || default_fail_queue_name
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Qwirk
|
2
2
|
|
3
3
|
# Base Worker Class for any class that will be processing requests from queues and replying
|
4
|
-
module
|
4
|
+
module ReplyWorker
|
5
5
|
include Worker
|
6
6
|
|
7
7
|
module ClassMethods
|
@@ -27,7 +27,7 @@ module Qwirk
|
|
27
27
|
rescue Exception => e
|
28
28
|
on_exception(e)
|
29
29
|
else
|
30
|
-
|
30
|
+
impl.send_response(message, config.marshaler.marshal(response))
|
31
31
|
end
|
32
32
|
post_request(object)
|
33
33
|
rescue Exception => e
|
@@ -49,7 +49,7 @@ module Qwirk
|
|
49
49
|
|
50
50
|
def on_exception(e)
|
51
51
|
begin
|
52
|
-
|
52
|
+
impl.send_exception(message, e)
|
53
53
|
rescue Exception => e
|
54
54
|
Qwirk.logger.error("Exception in exception reply: #{e.message}")
|
55
55
|
log_backtrace(e)
|
data/lib/qwirk/worker.rb
CHANGED
@@ -4,7 +4,7 @@ module Qwirk
|
|
4
4
|
# By default, it will consume messages from a queue with the class name minus the Worker postfix.
|
5
5
|
# For example, the queue call is unnecessary as it will default to a value of 'Foo' anyways:
|
6
6
|
# class FooWorker
|
7
|
-
# include Qwirk::
|
7
|
+
# include Qwirk::Worker
|
8
8
|
# queue 'Foo'
|
9
9
|
# def perform(obj)
|
10
10
|
# # Perform work on obj
|
@@ -15,7 +15,7 @@ module Qwirk
|
|
15
15
|
# each thread for a given worker will act as a separate subscriber.
|
16
16
|
# (For ActiveMQ - see http://activemq.apache.org/virtual-destinations.html):
|
17
17
|
# class FooWorker
|
18
|
-
# include Qwirk::
|
18
|
+
# include Qwirk::Worker
|
19
19
|
# topic 'Zulu'
|
20
20
|
# def perform(obj)
|
21
21
|
# # Perform work on obj
|
@@ -25,7 +25,7 @@ module Qwirk
|
|
25
25
|
# TODO (maybe):
|
26
26
|
# Filters can also be specified within the class:
|
27
27
|
# class FooWorker
|
28
|
-
# include Qwirk::
|
28
|
+
# include Qwirk::Worker
|
29
29
|
# filter 'age > 30'
|
30
30
|
# def perform(obj)
|
31
31
|
# # Perform work on obj
|
@@ -37,7 +37,7 @@ module Qwirk
|
|
37
37
|
include Qwirk::BaseWorker
|
38
38
|
|
39
39
|
attr_accessor :message
|
40
|
-
attr_reader :status, :
|
40
|
+
attr_reader :status, :impl, :start_worker_time, :start_read_time, :start_processing_time
|
41
41
|
|
42
42
|
module ClassMethods
|
43
43
|
def queue(name, opts={})
|
@@ -71,13 +71,12 @@ module Qwirk
|
|
71
71
|
end
|
72
72
|
|
73
73
|
# Defines the default value of the fail_queue_target. For extenders of this class, the default will be true
|
74
|
-
# but extenders can change this (
|
74
|
+
# but extenders can change this (ReplyWorker returns exceptions to the caller so it defaults to false).
|
75
75
|
def default_fail_queue_target
|
76
76
|
true
|
77
77
|
end
|
78
78
|
|
79
79
|
def queue_name(default_name)
|
80
|
-
puts "getting queue_name queue=#{@queue_name} topic=#{@topic_name} default=#{default_name}"
|
81
80
|
return @queue_name if @queue_name
|
82
81
|
return nil if @topic_name
|
83
82
|
return default_name
|
@@ -113,13 +112,16 @@ module Qwirk
|
|
113
112
|
base.extend(ClassMethods)
|
114
113
|
end
|
115
114
|
|
116
|
-
def
|
117
|
-
@status
|
118
|
-
@stopped
|
119
|
-
@processing_mutex
|
120
|
-
self.index
|
121
|
-
self.config
|
122
|
-
@
|
115
|
+
def init(index, worker_config)
|
116
|
+
@status = 'Started'
|
117
|
+
@stopped = false
|
118
|
+
@processing_mutex = Mutex.new
|
119
|
+
self.index = index
|
120
|
+
self.config = worker_config
|
121
|
+
@impl = worker_config.create_worker
|
122
|
+
end
|
123
|
+
|
124
|
+
def start
|
123
125
|
self.thread = Thread.new do
|
124
126
|
java.lang.Thread.current_thread.name = "Qwirk worker: #{self}" if RUBY_PLATFORM == 'jruby'
|
125
127
|
#Qwirk.logger.debug "#{worker}: Started thread with priority #{Thread.current.priority}"
|
@@ -131,17 +133,17 @@ module Qwirk
|
|
131
133
|
# clean up any resources. We don't want to clobber resources while a message is being processed so processing_mutex will surround
|
132
134
|
# message processessing and worker closing.
|
133
135
|
# From a JMS perspective, stop all workers (close consumer and session), stop the config.
|
134
|
-
# From an
|
136
|
+
# From an InMemory perspective, we don't want the workers stopping until all messages in the queue have been processed.
|
135
137
|
# Therefore we want to stop the
|
136
138
|
def stop
|
137
|
-
|
139
|
+
Qwirk.logger.debug "#{self}: In base worker stop"
|
138
140
|
@status = 'Stopping'
|
139
141
|
@stopped = true
|
140
142
|
@processing_mutex.synchronize do
|
141
|
-
# This should interrupt @
|
142
|
-
@
|
143
|
+
# This should interrupt @impl.receive_message above and cause it to return nil
|
144
|
+
@impl.stop
|
143
145
|
end
|
144
|
-
|
146
|
+
Qwirk.logger.debug "#{self}: base worker stop complete"
|
145
147
|
end
|
146
148
|
|
147
149
|
def perform(object)
|
@@ -157,25 +159,21 @@ module Qwirk
|
|
157
159
|
Qwirk.logger.error "\t#{e.backtrace.join("\n\t")}"
|
158
160
|
end
|
159
161
|
|
160
|
-
#########
|
161
|
-
protected
|
162
|
-
#########
|
163
|
-
|
164
162
|
# Start the event loop for handling messages off the queue
|
165
163
|
def event_loop
|
166
164
|
Qwirk.logger.debug "#{self}: Starting receive loop"
|
167
165
|
@start_worker_time = Time.now
|
168
|
-
while !@stopped && !config.
|
169
|
-
|
166
|
+
while !@stopped && !config.stopped
|
167
|
+
Qwirk.logger.debug "#{self}: Waiting for read"
|
170
168
|
@start_read_time = Time.now
|
171
|
-
msg = @
|
169
|
+
msg = @impl.receive_message
|
172
170
|
if msg
|
173
171
|
@start_processing_time = Time.now
|
174
172
|
Qwirk.logger.debug {"#{self}: Done waiting for read in #{@start_processing_time - @start_read_time} seconds"}
|
175
173
|
delta = config.timer.measure do
|
176
174
|
@processing_mutex.synchronize do
|
177
175
|
on_message(msg)
|
178
|
-
@
|
176
|
+
@impl.acknowledge_message(msg)
|
179
177
|
end
|
180
178
|
end
|
181
179
|
Qwirk.logger.info {"#{self}::on_message (#{'%.1f' % delta}ms)"} if self.config.log_times
|
@@ -189,7 +187,7 @@ module Qwirk
|
|
189
187
|
ensure
|
190
188
|
@status = 'Stopped'
|
191
189
|
# TODO: necessary?
|
192
|
-
@
|
190
|
+
@impl.stop
|
193
191
|
Qwirk.logger.flush if Qwirk.logger.respond_to?(:flush)
|
194
192
|
config.worker_stopped(self)
|
195
193
|
end
|
@@ -197,7 +195,7 @@ module Qwirk
|
|
197
195
|
def on_message(message)
|
198
196
|
# TBD - Is it necessary to provide underlying message to worker? Should we generically provide access to message attributes? Do filters somehow fit in here?
|
199
197
|
@message = message
|
200
|
-
object = @
|
198
|
+
object = @impl.message_to_object(message)
|
201
199
|
Qwirk.logger.debug {"#{self}: Received Object: #{object}"}
|
202
200
|
perform(object)
|
203
201
|
rescue Exception => e
|
@@ -209,7 +207,7 @@ module Qwirk
|
|
209
207
|
def on_exception(e)
|
210
208
|
Qwirk.logger.error "#{self}: Messaging Exception: #{e.message}"
|
211
209
|
log_backtrace(e)
|
212
|
-
@
|
210
|
+
@impl.handle_failure(message, e, @fail_queue_name) if @fail_queue_name
|
213
211
|
rescue Exception => e
|
214
212
|
Qwirk.logger.error "#{self}: Exception in exception reply: #{e.message}"
|
215
213
|
log_backtrace(e)
|
data/test/jms_fail_test.rb
CHANGED
@@ -7,7 +7,7 @@ require 'erb'
|
|
7
7
|
# NOTE: This test requires a running ActiveMQ server
|
8
8
|
|
9
9
|
class ExceptionWorker
|
10
|
-
include Qwirk::
|
10
|
+
include Qwirk::Adapter::JMS::Worker
|
11
11
|
def perform(obj)
|
12
12
|
puts "#{name} received #{obj} but raising exception"
|
13
13
|
raise 'foobar'
|
@@ -17,8 +17,8 @@ class ExceptionWorker
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
class
|
21
|
-
include Qwirk::
|
20
|
+
class ExceptionReplyWorker
|
21
|
+
include Qwirk::Adapter::JMS::ReplyWorker
|
22
22
|
|
23
23
|
def request(obj)
|
24
24
|
puts "#{name} received #{obj} but raising exception"
|
@@ -31,7 +31,7 @@ end
|
|
31
31
|
|
32
32
|
# This will read from the queue that ExceptionWorker fails to
|
33
33
|
class ExceptionFailWorker
|
34
|
-
include Qwirk::
|
34
|
+
include Qwirk::Adapter::JMS::Worker
|
35
35
|
|
36
36
|
@@my_hash = {}
|
37
37
|
|
@@ -49,7 +49,7 @@ class JMSFailTest < Test::Unit::TestCase
|
|
49
49
|
|
50
50
|
def assert_fail_queue(queue_name, fail_queue_name, value, is_fail_queue_expected)
|
51
51
|
# Publish to Exception that will throw exception which will put on ExceptionFail queue
|
52
|
-
publisher = Qwirk::
|
52
|
+
publisher = Qwirk::Adapter::JMS::Publisher.new(:queue_name => queue_name, :marshal => :string)
|
53
53
|
puts "Publishing #{value} to #{queue_name}"
|
54
54
|
publisher.publish(value)
|
55
55
|
sleep 1
|
@@ -60,7 +60,7 @@ class JMSFailTest < Test::Unit::TestCase
|
|
60
60
|
context 'jms' do
|
61
61
|
setup do
|
62
62
|
config = YAML.load(ERB.new(File.read(File.join(File.dirname(__FILE__), 'jms.yml'))).result(binding))
|
63
|
-
Qwirk::
|
63
|
+
Qwirk::Adapter::JMS::Connection.init(config)
|
64
64
|
end
|
65
65
|
|
66
66
|
teardown do
|
@@ -97,28 +97,28 @@ class JMSFailTest < Test::Unit::TestCase
|
|
97
97
|
|
98
98
|
# Should NOT receive message on the fail worker
|
99
99
|
name = 'ExceptionRequest'
|
100
|
-
@manager.add(
|
100
|
+
@manager.add(ExceptionReplyWorker, 1)
|
101
101
|
@manager.add(ExceptionFailWorker, 1, :name => "#{name}Fail")
|
102
102
|
|
103
103
|
# Should NOT receive message on the fail worker when using specified names
|
104
104
|
name = 'ExceptionRequestNameSpecified'
|
105
|
-
@manager.add(
|
105
|
+
@manager.add(ExceptionReplyWorker, 1, :name => name)
|
106
106
|
@manager.add(ExceptionFailWorker, 1, :name => "#{name}Fail")
|
107
107
|
|
108
108
|
# Should receive message on the fail worker when using specified names and fail_queue set true
|
109
109
|
name = 'ExceptionRequestFailQueueTrue'
|
110
|
-
@manager.add(
|
110
|
+
@manager.add(ExceptionReplyWorker, 1, :name => name, :fail_queue => true)
|
111
111
|
@manager.add(ExceptionFailWorker, 1, :name => "#{name}Fail")
|
112
112
|
|
113
113
|
# Should NOT receive message on the fail worker when using specified names and fail_queue set false
|
114
114
|
name = 'ExceptionRequestFailQueueFalse'
|
115
|
-
@manager.add(
|
115
|
+
@manager.add(ExceptionReplyWorker, 1, :name => name, :fail_queue => false)
|
116
116
|
@manager.add(ExceptionFailWorker, 1, :name => "#{name}Fail")
|
117
117
|
|
118
118
|
# Should NOT receive message on the fail worker when using specified names and fail_queue set false
|
119
119
|
name = 'ExceptionRequestFailQueueSpecified'
|
120
120
|
fail_queue = 'MyRequestFailQueue'
|
121
|
-
@manager.add(
|
121
|
+
@manager.add(ExceptionReplyWorker, 1, :name => name, :fail_queue => fail_queue)
|
122
122
|
@manager.add(ExceptionFailWorker, 1, :name => fail_queue)
|
123
123
|
|
124
124
|
sleep 1
|