modern_times 0.2.11 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +114 -80
- data/VERSION +1 -1
- data/examples/advanced_requestor/README +15 -0
- data/examples/advanced_requestor/base_request_worker.rb +13 -0
- data/examples/advanced_requestor/char_count_worker.rb +11 -0
- data/examples/advanced_requestor/exception_raiser_worker.rb +10 -0
- data/examples/advanced_requestor/length_worker.rb +9 -0
- data/examples/advanced_requestor/manager.rb +22 -0
- data/examples/advanced_requestor/modern_times.yml +32 -0
- data/examples/advanced_requestor/print_worker.rb +9 -0
- data/examples/advanced_requestor/publish.rb +46 -0
- data/examples/advanced_requestor/reverse_worker.rb +9 -0
- data/examples/advanced_requestor/triple_worker.rb +9 -0
- data/examples/requestor/request.rb +3 -3
- data/examples/requestor/reverse_echo_worker.rb +1 -2
- data/lib/modern_times.rb +1 -1
- data/lib/modern_times/base/supervisor.rb +2 -0
- data/lib/modern_times/base/worker.rb +5 -3
- data/lib/modern_times/jms.rb +2 -0
- data/lib/modern_times/jms/connection.rb +7 -0
- data/lib/modern_times/jms/publish_handle.rb +219 -0
- data/lib/modern_times/jms/publisher.rb +55 -29
- data/lib/modern_times/{jms_requestor/worker.rb → jms/request_worker.rb} +29 -51
- data/lib/modern_times/jms/supervisor.rb +30 -0
- data/lib/modern_times/jms/supervisor_mbean.rb +17 -1
- data/lib/modern_times/jms/worker.rb +43 -40
- data/lib/modern_times/manager.rb +6 -2
- data/lib/modern_times/marshal_strategy.rb +14 -17
- data/lib/modern_times/marshal_strategy/bson.rb +2 -0
- data/lib/modern_times/marshal_strategy/json.rb +3 -0
- data/lib/modern_times/marshal_strategy/ruby.rb +3 -0
- data/lib/modern_times/marshal_strategy/string.rb +3 -0
- data/lib/modern_times/marshal_strategy/yaml.rb +3 -0
- data/lib/modern_times/railsable.rb +7 -14
- data/lib/modern_times/time_track.rb +84 -0
- data/test/jms.yml +1 -0
- data/test/jms_failure_test.rb +128 -0
- data/test/jms_requestor_block_test.rb +275 -0
- data/test/jms_requestor_test.rb +71 -96
- data/test/jms_test.rb +59 -78
- data/test/marshal_strategy_test.rb +1 -3
- metadata +29 -14
- data/examples/exception_test/bar_worker.rb +0 -8
- data/examples/exception_test/base_worker.rb +0 -23
- data/examples/exception_test/manager.rb +0 -11
- data/lib/modern_times/jms_requestor.rb +0 -10
- data/lib/modern_times/jms_requestor/request_handle.rb +0 -42
- data/lib/modern_times/jms_requestor/requestor.rb +0 -56
- data/lib/modern_times/jms_requestor/supervisor.rb +0 -45
- data/lib/modern_times/jms_requestor/supervisor_mbean.rb +0 -21
@@ -19,15 +19,15 @@ $sim_count = (ARGV[3] || 1).to_i
|
|
19
19
|
|
20
20
|
config = YAML.load(ERB.new(File.read(File.join(File.dirname(__FILE__), '..', 'jms.yml'))).result(binding))
|
21
21
|
ModernTimes::JMS::Connection.init(config)
|
22
|
-
$
|
22
|
+
$publisher = ModernTimes::JMS::Publisher.new(:queue_name => ReverseEchoWorker.default_name, :response =>true, :marshal => :string)
|
23
23
|
|
24
24
|
def make_request(ident='')
|
25
25
|
puts "#{ident}Making request at #{Time.now.to_f}"
|
26
|
-
handle = $
|
26
|
+
handle = $publisher.publish("#{ident}#{$echo_string}")
|
27
27
|
# Here's where we'd go off and do other work
|
28
28
|
sleep $sleep_time
|
29
29
|
puts "#{ident}Finished sleeping at #{Time.now.to_f}"
|
30
|
-
response = handle.read_response
|
30
|
+
response = handle.read_response($timeout)
|
31
31
|
puts "#{ident}Received at #{Time.now.to_f}: #{response}"
|
32
32
|
rescue Exception => e
|
33
33
|
puts "#{ident}Exception: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
|
data/lib/modern_times.rb
CHANGED
@@ -3,11 +3,11 @@ require 'modern_times/remote_exception'
|
|
3
3
|
require 'modern_times/marshal_strategy'
|
4
4
|
require 'modern_times/base'
|
5
5
|
require 'modern_times/jms'
|
6
|
-
require 'modern_times/jms_requestor'
|
7
6
|
require 'modern_times/manager_mbean'
|
8
7
|
require 'modern_times/manager'
|
9
8
|
require 'modern_times/loggable'
|
10
9
|
require 'modern_times/railsable'
|
10
|
+
require 'modern_times/time_track'
|
11
11
|
|
12
12
|
module ModernTimes
|
13
13
|
extend ModernTimes::Loggable
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module ModernTimes
|
2
2
|
module Base
|
3
3
|
module Worker
|
4
|
-
|
4
|
+
attr_reader :name, :options
|
5
|
+
attr_accessor :index, :thread
|
5
6
|
|
6
7
|
module ClassMethods
|
7
8
|
def default_name
|
@@ -18,8 +19,9 @@ module ModernTimes
|
|
18
19
|
base.extend(ClassMethods)
|
19
20
|
end
|
20
21
|
|
21
|
-
def initialize(
|
22
|
-
@name =
|
22
|
+
def initialize(options={})
|
23
|
+
@name = options[:name] || self.class.default_name
|
24
|
+
@options = options
|
23
25
|
end
|
24
26
|
|
25
27
|
# One time initialization prior to first thread
|
data/lib/modern_times/jms.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'modern_times/jms/connection'
|
2
2
|
require 'modern_times/jms/consumer'
|
3
3
|
require 'modern_times/jms/publisher'
|
4
|
+
require 'modern_times/jms/publish_handle'
|
4
5
|
require 'modern_times/jms/supervisor_mbean'
|
5
6
|
require 'modern_times/jms/supervisor'
|
6
7
|
require 'modern_times/jms/worker'
|
8
|
+
require 'modern_times/jms/request_worker'
|
7
9
|
|
8
10
|
module ModernTimes
|
9
11
|
module JMS
|
@@ -11,6 +11,9 @@ module ModernTimes
|
|
11
11
|
def init(config)
|
12
12
|
@config = config
|
13
13
|
@inited = true
|
14
|
+
@log_times = config.delete(:log_times)
|
15
|
+
# Default to true
|
16
|
+
@log_times = true if @log_times.nil?
|
14
17
|
|
15
18
|
# Let's not create a session_pool unless we're going to use it
|
16
19
|
@session_pool_mutex = Mutex.new
|
@@ -27,6 +30,10 @@ module ModernTimes
|
|
27
30
|
@inited
|
28
31
|
end
|
29
32
|
|
33
|
+
def log_times?
|
34
|
+
@log_times
|
35
|
+
end
|
36
|
+
|
30
37
|
# Create a session targeted for a consumer (producers should use the session_pool)
|
31
38
|
def create_consumer_session
|
32
39
|
connection.create_session(@config || {})
|
@@ -0,0 +1,219 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module ModernTimes
|
5
|
+
module JMS
|
6
|
+
class PublishHandle
|
7
|
+
def initialize(publisher, jms_message_id, start)
|
8
|
+
@publisher = publisher
|
9
|
+
@jms_message_id = jms_message_id
|
10
|
+
@start = start
|
11
|
+
# Dummy hash will store all the responses from the RequestWorker's matching our publishing destination.
|
12
|
+
@dummy_hash = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
# Waits the given timeout for a response message on the queue.
|
16
|
+
#
|
17
|
+
# If called w/o a block:
|
18
|
+
# Returns the message
|
19
|
+
# Returns nil on timeout
|
20
|
+
# Raises RemoteException on a remote exception
|
21
|
+
#
|
22
|
+
# If called with a block, for instance:
|
23
|
+
# handle.read_response(timeout) do |response|
|
24
|
+
# response.on_message 'CharCount' do |hash|
|
25
|
+
# puts "CharCount returned #{hash.inspect}"
|
26
|
+
# end
|
27
|
+
# response.on_message 'Length', 'Reverse' do |val|
|
28
|
+
# puts "#{response.name} returned #{val}"
|
29
|
+
# end
|
30
|
+
# response.on_message 'ExceptionRaiser' do |val|
|
31
|
+
# puts "#{response.name} didn't raise an exception but returned #{val}"
|
32
|
+
# end
|
33
|
+
# response.on_timeout 'Reverse' do
|
34
|
+
# puts "Reverse has it's own timeout handler"
|
35
|
+
# end
|
36
|
+
# response.on_timeout do
|
37
|
+
# puts "#{response.name} did not respond in time"
|
38
|
+
# end
|
39
|
+
# response.on_remote_exception 'ExceptionRaiser' do
|
40
|
+
# puts "It figures that ExceptionRaiser would raise an exception"
|
41
|
+
# end
|
42
|
+
# response.on_remote_exception do |e|
|
43
|
+
# puts "#{response.name} raised an exception #{e.message}\n\t#{e.backtrace.join("\n\t")}"
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# The specified blocks will be called for each response. For instance, LengthWorker#request
|
48
|
+
# might return 4 and "Length returned 4" would be displayed. If it failed to respond within the
|
49
|
+
# timeout, then "Length did no respond in time" would be displayed.
|
50
|
+
# For Workers that raise an exception, they will either be handled by their specific handler if it exists or
|
51
|
+
# the default exception handler. If that doesn't exist either, then the RemoteException will be raised for the
|
52
|
+
# whole read_response call. Timeouts will also be handled by the default timeout handler unless a specific one
|
53
|
+
# is specified. All messages must have a specific handler specified because the call won't return until all
|
54
|
+
# specified handlers either return, timeout, or return an exception.
|
55
|
+
#
|
56
|
+
def read_response(timeout, &block)
|
57
|
+
reply_queue = @publisher.reply_queue
|
58
|
+
raise "Invalid call to read_response for #{@publisher}, not setup for responding" unless reply_queue
|
59
|
+
options = { :destination => reply_queue, :selector => "JMSCorrelationID = '#{@jms_message_id}'" }
|
60
|
+
ModernTimes::JMS::Connection.session_pool.consumer(options) do |session, consumer|
|
61
|
+
do_read_response(consumer, timeout, &block)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def dummy_read_response(timeout, &block)
|
66
|
+
raise "Invalid call to read_response for #{@publisher}, not setup for responding" unless @publisher.response
|
67
|
+
do_read_response(nil, timeout, &block)
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_dummy_response(name, object)
|
71
|
+
@dummy_hash[name] = object
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.setup_dummy_handling
|
75
|
+
alias_method :real_read_response, :read_response
|
76
|
+
alias_method :read_response, :dummy_read_response
|
77
|
+
alias_method :real_read_single_response, :read_single_response
|
78
|
+
alias_method :read_single_response, :dummy_read_single_response
|
79
|
+
end
|
80
|
+
|
81
|
+
# For testing
|
82
|
+
def self.clear_dummy_handling
|
83
|
+
alias_method :dummy_read_response, :read_response
|
84
|
+
alias_method :read_response, :real_read_response
|
85
|
+
alias_method :dummy_read_single_response, :read_single_response
|
86
|
+
alias_method :read_single_response, :real_read_single_response
|
87
|
+
end
|
88
|
+
#######
|
89
|
+
private
|
90
|
+
#######
|
91
|
+
|
92
|
+
class WorkerResponse
|
93
|
+
attr_reader :name, :start
|
94
|
+
|
95
|
+
def initialize(start)
|
96
|
+
@start = start
|
97
|
+
@message_hash = {}
|
98
|
+
@timeout_hash = {}
|
99
|
+
@exception_hash = {}
|
100
|
+
@default_timeout_block = nil
|
101
|
+
@default_exception_block = nil
|
102
|
+
@done_array = []
|
103
|
+
end
|
104
|
+
|
105
|
+
# Msecs since publish
|
106
|
+
def msec_delta
|
107
|
+
(Time.now - @start) * 1000
|
108
|
+
end
|
109
|
+
|
110
|
+
def on_message(*names, &block)
|
111
|
+
raise 'Must explicitly define all message handlers so we know that we\'re done' if names.empty?
|
112
|
+
names.each {|name| @message_hash[name] = block}
|
113
|
+
end
|
114
|
+
|
115
|
+
def on_timeout(*names, &block)
|
116
|
+
if names.empty?
|
117
|
+
@default_timeout_block = block
|
118
|
+
else
|
119
|
+
names.each {|name| @timeout_hash[name] = block}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def on_remote_exception(*names, &block)
|
124
|
+
if names.empty?
|
125
|
+
@default_exception_block = block
|
126
|
+
else
|
127
|
+
names.each {|name| @exception_hash[name] = block}
|
128
|
+
end
|
129
|
+
@remote_exception_block = block
|
130
|
+
end
|
131
|
+
|
132
|
+
def make_message_call(name, obj)
|
133
|
+
# Give the client access to the name
|
134
|
+
@name = name
|
135
|
+
block = @message_hash[name]
|
136
|
+
block.call(obj) if block
|
137
|
+
@done_array << name
|
138
|
+
end
|
139
|
+
|
140
|
+
def done?
|
141
|
+
(@message_hash.keys - @done_array).empty?
|
142
|
+
end
|
143
|
+
|
144
|
+
def make_timeout_calls
|
145
|
+
@timeouts = @message_hash.keys - @done_array
|
146
|
+
@timeouts.each do |name|
|
147
|
+
# Give the client access to the name
|
148
|
+
@name = name
|
149
|
+
block = @timeout_hash[name] || @default_timeout_block
|
150
|
+
block.call if block
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def make_exception_call(name, e)
|
155
|
+
@name = name
|
156
|
+
block = @exception_hash[name] || @default_exception_block
|
157
|
+
if block
|
158
|
+
block.call(e)
|
159
|
+
@done_array << name
|
160
|
+
else
|
161
|
+
raise e
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def do_read_response(consumer, timeout, &block)
|
167
|
+
if block_given?
|
168
|
+
return read_multiple_response(consumer, timeout, &block)
|
169
|
+
else
|
170
|
+
response = read_single_response(consumer, timeout)
|
171
|
+
raise response if response.kind_of?(ModernTimes::RemoteException)
|
172
|
+
return response
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def read_single_response(consumer, timeout)
|
177
|
+
message = nil
|
178
|
+
leftover_timeout = ((@start + timeout - Time.now) * 1000).to_i
|
179
|
+
if leftover_timeout > 100
|
180
|
+
message = consumer.receive(leftover_timeout)
|
181
|
+
else
|
182
|
+
#message = consumer.receive_no_wait
|
183
|
+
message = consumer.receive(100)
|
184
|
+
end
|
185
|
+
return nil unless message
|
186
|
+
@name = message['worker']
|
187
|
+
if error_yaml = message['exception']
|
188
|
+
return ModernTimes::RemoteException.from_hash(YAML.load(error_yaml))
|
189
|
+
end
|
190
|
+
marshaler = ModernTimes::MarshalStrategy.find(message['marshal'] || :ruby)
|
191
|
+
return marshaler.unmarshal(message.data)
|
192
|
+
end
|
193
|
+
|
194
|
+
def dummy_read_single_response(consumer, timeout)
|
195
|
+
@name = @dummy_hash.keys.first
|
196
|
+
return nil unless @name
|
197
|
+
return @dummy_hash.delete(@name)
|
198
|
+
end
|
199
|
+
|
200
|
+
def read_multiple_response(consumer, timeout, &block)
|
201
|
+
worker_response = WorkerResponse.new(@start)
|
202
|
+
yield worker_response
|
203
|
+
|
204
|
+
until worker_response.done? do
|
205
|
+
response = read_single_response(consumer, timeout)
|
206
|
+
if !response
|
207
|
+
worker_response.make_timeout_calls
|
208
|
+
return
|
209
|
+
end
|
210
|
+
if response.kind_of?(ModernTimes::RemoteException)
|
211
|
+
worker_response.make_exception_call(@name, response)
|
212
|
+
else
|
213
|
+
worker_response.make_message_call(@name, response)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -4,20 +4,25 @@ require 'jms'
|
|
4
4
|
module ModernTimes
|
5
5
|
module JMS
|
6
6
|
class Publisher
|
7
|
-
attr_reader :producer_options, :persistent, :marshaler
|
7
|
+
attr_reader :producer_options, :persistent, :marshaler, :reply_queue, :response
|
8
|
+
|
9
|
+
@@dummy_publishing = false
|
8
10
|
|
9
11
|
# Parameters:
|
10
12
|
# One of the following must be specified
|
11
|
-
# :queue_name
|
12
|
-
# :topic_name
|
13
|
+
# :queue_name => String: Name of the Queue to publish to
|
14
|
+
# :topic_name => String: Name of the Topic to publish to
|
13
15
|
# :virtual_topic_name => String: Name of the Virtual Topic to publish to
|
14
16
|
# (ActiveMQ only, see http://activemq.apache.org/virtual-destinations.html
|
15
|
-
# :destination=> Explicit javax::Jms::Destination to use
|
17
|
+
# :destination => Explicit javax::Jms::Destination to use
|
16
18
|
# Optional:
|
17
|
-
# :persistent
|
18
|
-
# :marshal
|
19
|
-
#
|
19
|
+
# :persistent => true or false (defaults to false)
|
20
|
+
# :marshal => Symbol: One of :ruby, :string, :json, :bson, :yaml or any registered types (See ModernTimes::MarshalStrategy), defaults to :ruby
|
21
|
+
# => Module: Module that defines marshal and unmarshal method
|
22
|
+
# :time_to_live => expiration time in ms for the message
|
23
|
+
# :response => if true, a temporary reply queue will be setup for handling responses (defaults to false)
|
20
24
|
def initialize(options)
|
25
|
+
raise "ModernTimes::JMS::Connection has not been initialized" unless ModernTimes::JMS::Connection.inited? || @@dummy_publishing
|
21
26
|
producer_keys = [:queue_name, :topic_name, :virtual_topic_name, :destination]
|
22
27
|
@producer_options = options.reject {|k,v| !producer_keys.include?(k)}
|
23
28
|
raise "One of #{producer_keys.join(',')} must be given in #{self.class.name}" if @producer_options.empty?
|
@@ -31,43 +36,67 @@ module ModernTimes
|
|
31
36
|
# If we're in dummy mode, this probably won't be defined
|
32
37
|
#@persistent = options[:persistent] ? ::JMS::DeliveryMode::PERSISTENT : ::JMS::DeliveryMode::NON_PERSISTENT
|
33
38
|
@persistent = options[:persistent] ? :persistent : :non_persistent
|
34
|
-
@
|
39
|
+
@marshal = options[:marshal] || :ruby
|
40
|
+
@marshaler = ModernTimes::MarshalStrategy.find(@marshal)
|
35
41
|
@time_to_live = options[:time_to_live]
|
42
|
+
|
43
|
+
@reply_queue = nil
|
44
|
+
@response = options[:response]
|
45
|
+
if !@@dummy_publishing && @response
|
46
|
+
ModernTimes::JMS::Connection.session_pool.session do |session|
|
47
|
+
@reply_queue = session.create_destination(:queue_name => :temporary)
|
48
|
+
end
|
49
|
+
end
|
36
50
|
end
|
37
51
|
|
38
52
|
# Publish the given object to the address.
|
39
53
|
def publish(object, props={})
|
54
|
+
start = Time.now
|
40
55
|
message = nil
|
41
56
|
Connection.session_pool.producer(@real_producer_options) do |session, producer|
|
42
57
|
producer.time_to_live = @time_to_live if @time_to_live
|
43
58
|
message = ModernTimes::JMS.create_message(session, @marshaler, object)
|
44
59
|
message.jms_delivery_mode_sym = @persistent
|
60
|
+
message.jms_reply_to = @reply_queue if @reply_queue
|
61
|
+
message['marshal'] = @marshal.to_s
|
45
62
|
props.each do |key, value|
|
46
63
|
message.send("#{key}=", value)
|
47
64
|
end
|
48
|
-
# TODO: Is send_with_retry possible?
|
49
|
-
#producer.send_with_retry(message)
|
50
65
|
producer.send(message)
|
51
66
|
end
|
52
|
-
return message.jms_message_id
|
67
|
+
return PublishHandle.new(self, message.jms_message_id, start)
|
53
68
|
end
|
54
69
|
|
55
70
|
# For non-configured Rails projects, The above publish method will be overridden to
|
56
71
|
# call this publish method instead which calls all the JMS workers that
|
57
72
|
# operate on the given address.
|
58
73
|
def dummy_publish(object, props={})
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
worker.
|
74
|
+
dummy_handle = PublishHandle.new(self, nil, Time.now)
|
75
|
+
# Model real queue marshaling/unmarshaling
|
76
|
+
trans_object = @marshaler.unmarshal(@marshaler.marshal(object))
|
77
|
+
@@workers.each do |worker|
|
78
|
+
if ModernTimes::JMS.same_destination?(@producer_options, worker.class.destination_options)
|
79
|
+
if worker.kind_of?(RequestWorker)
|
80
|
+
ModernTimes.logger.debug "Dummy request publishing #{trans_object} to #{worker}"
|
81
|
+
m = worker.marshaler
|
82
|
+
# Model real queue marshaling/unmarshaling
|
83
|
+
begin
|
84
|
+
response_object = m.unmarshal(m.marshal(worker.request(trans_object)))
|
85
|
+
dummy_handle.add_dummy_response(worker.name, response_object)
|
86
|
+
rescue Exception => e
|
87
|
+
dummy_handle.add_dummy_response(worker.name, ModernTimes::RemoteException.new(e))
|
88
|
+
end
|
89
|
+
elsif worker.kind_of?(Worker)
|
90
|
+
ModernTimes.logger.debug "Dummy publishing #{trans_object} to #{worker}"
|
91
|
+
begin
|
92
|
+
worker.perform(trans_object)
|
93
|
+
rescue Exception => e
|
94
|
+
ModernTimes.logger.error("#{worker} Exception: #{e.message}\n\t#{e.backtrace.join("\n\t")}")
|
95
|
+
end
|
96
|
+
end
|
65
97
|
end
|
66
98
|
end
|
67
|
-
|
68
|
-
@@dummy_cache[correlation_id] = object
|
69
|
-
end
|
70
|
-
return @@message_id.to_s
|
99
|
+
return dummy_handle
|
71
100
|
end
|
72
101
|
|
73
102
|
def to_s
|
@@ -75,23 +104,20 @@ module ModernTimes
|
|
75
104
|
end
|
76
105
|
|
77
106
|
def self.setup_dummy_publishing(workers)
|
78
|
-
|
79
|
-
@@
|
80
|
-
@@dummy_cache = {}
|
81
|
-
@@worker_instances = workers.map {|worker| worker.new}
|
107
|
+
@@dummy_publishing = true
|
108
|
+
@@workers = workers
|
82
109
|
alias_method :real_publish, :publish
|
83
110
|
alias_method :publish, :dummy_publish
|
111
|
+
PublishHandle.setup_dummy_handling
|
84
112
|
end
|
85
113
|
|
86
114
|
# For testing
|
87
115
|
def self.clear_dummy_publishing
|
116
|
+
@@dummy_publishing = false
|
88
117
|
alias_method :dummy_publish, :publish
|
89
118
|
alias_method :publish, :real_publish
|
90
119
|
#remove_method :real_publish
|
91
|
-
|
92
|
-
|
93
|
-
def self.dummy_cache(correlation_id)
|
94
|
-
@@dummy_cache.delete(correlation_id)
|
120
|
+
PublishHandle.clear_dummy_handling
|
95
121
|
end
|
96
122
|
end
|
97
123
|
end
|