gz_activemessaging 0.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +40 -0
  3. data/Appraisals +19 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +87 -0
  6. data/README.md +27 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/activemessaging.gemspec +137 -0
  10. data/gemfiles/activesupport23.gemfile +10 -0
  11. data/gemfiles/activesupport23.gemfile.lock +51 -0
  12. data/gemfiles/activesupport30.gemfile +11 -0
  13. data/gemfiles/activesupport30.gemfile.lock +53 -0
  14. data/gemfiles/activesupport31.gemfile +11 -0
  15. data/gemfiles/activesupport31.gemfile.lock +55 -0
  16. data/gemfiles/activesupport32.gemfile +10 -0
  17. data/gemfiles/activesupport32.gemfile.lock +55 -0
  18. data/generators/a13g_test_harness/a13g_test_harness_generator.rb +19 -0
  19. data/generators/a13g_test_harness/templates/active_messaging_test.rhtml +13 -0
  20. data/generators/a13g_test_harness/templates/active_messaging_test_controller.rb +29 -0
  21. data/generators/a13g_test_harness/templates/index.rhtml +17 -0
  22. data/generators/filter/USAGE +0 -0
  23. data/generators/filter/filter_generator.rb +19 -0
  24. data/generators/filter/templates/filter.rb +12 -0
  25. data/generators/filter/templates/filter_test.rb +28 -0
  26. data/generators/processor/USAGE +8 -0
  27. data/generators/processor/processor_generator.rb +31 -0
  28. data/generators/processor/templates/application_processor.rb +18 -0
  29. data/generators/processor/templates/broker.yml +140 -0
  30. data/generators/processor/templates/jruby_poller +117 -0
  31. data/generators/processor/templates/messaging.rb +12 -0
  32. data/generators/processor/templates/poller +25 -0
  33. data/generators/processor/templates/poller.rb +26 -0
  34. data/generators/processor/templates/processor.rb +8 -0
  35. data/generators/processor/templates/processor_test.rb +20 -0
  36. data/generators/tracer/USAGE +8 -0
  37. data/generators/tracer/templates/controller.rb +14 -0
  38. data/generators/tracer/templates/helper.rb +2 -0
  39. data/generators/tracer/templates/index.rhtml +4 -0
  40. data/generators/tracer/templates/layout.rhtml +16 -0
  41. data/generators/tracer/templates/trace_processor.rb +100 -0
  42. data/generators/tracer/tracer_generator.rb +25 -0
  43. data/init.rb +1 -0
  44. data/lib/activemessaging.rb +133 -0
  45. data/lib/activemessaging/adapter.rb +20 -0
  46. data/lib/activemessaging/adapters/amqp.rb +215 -0
  47. data/lib/activemessaging/adapters/asqs.rb +487 -0
  48. data/lib/activemessaging/adapters/base.rb +71 -0
  49. data/lib/activemessaging/adapters/beanstalk.rb +88 -0
  50. data/lib/activemessaging/adapters/jms.rb +243 -0
  51. data/lib/activemessaging/adapters/reliable_msg.rb +186 -0
  52. data/lib/activemessaging/adapters/stomp.rb +212 -0
  53. data/lib/activemessaging/adapters/synch.rb +95 -0
  54. data/lib/activemessaging/adapters/test.rb +137 -0
  55. data/lib/activemessaging/adapters/wmq.rb +193 -0
  56. data/lib/activemessaging/base_message.rb +28 -0
  57. data/lib/activemessaging/filter.rb +29 -0
  58. data/lib/activemessaging/gateway.rb +429 -0
  59. data/lib/activemessaging/message_sender.rb +30 -0
  60. data/lib/activemessaging/named_base.rb +54 -0
  61. data/lib/activemessaging/processor.rb +44 -0
  62. data/lib/activemessaging/railtie.rb +26 -0
  63. data/lib/activemessaging/test_helper.rb +189 -0
  64. data/lib/activemessaging/threaded_poller.rb +234 -0
  65. data/lib/activemessaging/trace_filter.rb +34 -0
  66. data/lib/generators/active_messaging/install/USAGE +21 -0
  67. data/lib/generators/active_messaging/install/install_generator.rb +39 -0
  68. data/lib/generators/active_messaging/install/templates/application_processor.rb +18 -0
  69. data/lib/generators/active_messaging/install/templates/broker.yml +139 -0
  70. data/lib/generators/active_messaging/install/templates/poller +24 -0
  71. data/lib/generators/active_messaging/install/templates/poller.rb +22 -0
  72. data/lib/generators/active_messaging/install/templates/threaded_poller +46 -0
  73. data/lib/generators/active_messaging/processor/USAGE +2 -0
  74. data/lib/generators/active_messaging/processor/processor_generator.rb +39 -0
  75. data/lib/generators/active_messaging/processor/templates/messaging.rb +12 -0
  76. data/lib/generators/active_messaging/processor/templates/processor.rb +8 -0
  77. data/lib/generators/active_messaging/processor/templates/processor_spec.rb +24 -0
  78. data/lib/generators/active_messaging/processor/templates/processor_test.rb +20 -0
  79. data/lib/tasks/start_consumers.rake +8 -0
  80. data/poller.rb +14 -0
  81. data/test/all_tests.rb +10 -0
  82. data/test/app/config/broker.yml +4 -0
  83. data/test/asqs_test.rb +125 -0
  84. data/test/config_test.rb +42 -0
  85. data/test/filter_test.rb +131 -0
  86. data/test/gateway_test.rb +220 -0
  87. data/test/jms_test.rb +64 -0
  88. data/test/reliable_msg_test.rb +83 -0
  89. data/test/stomp_test.rb +168 -0
  90. data/test/test_helper.rb +36 -0
  91. data/test/tracer_test.rb +57 -0
  92. metadata +202 -0
@@ -0,0 +1,30 @@
1
+ require 'logger'
2
+
3
+ module ActiveMessaging
4
+
5
+ # This is a module so that we can send messages from (for example) web page controllers, or can receive a single message
6
+ module MessageSender
7
+
8
+ def self.included(included_by)
9
+ class << included_by
10
+ def publishes_to destination_name
11
+ ActiveMessaging::Gateway.find_destination(destination_name)
12
+ end
13
+
14
+ def receives_from destination_name
15
+ ActiveMessaging::Gateway.find_destination(destination_name)
16
+ end
17
+ end
18
+ end
19
+
20
+ def publish destination_name, message, headers={}, timeout=10
21
+ ActiveMessaging::Gateway.publish(destination_name, message, self.class, headers, timeout)
22
+ end
23
+
24
+ def receive destination_name, headers={}, timeout=10
25
+ ActiveMessaging::Gateway.receive(destination_name, self.class, headers, timeout)
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,54 @@
1
+ #Adapter to rubigen / rails
2
+
3
+ if defined?(Rails)
4
+ class NamedBase < Rails::Generator::NamedBase
5
+ end
6
+ else
7
+ class NamedBase < RubiGen::Base
8
+ attr_reader :name, :class_name, :singular_name, :plural_name
9
+ attr_reader :class_path, :file_path, :class_nesting, :class_nesting_depth
10
+ alias_method :file_name, :singular_name
11
+ alias_method :actions, :args
12
+
13
+ def initialize(runtime_args, runtime_options={})
14
+ super
15
+
16
+ base_name = self.args.first
17
+ assign_names!(base_name)
18
+ end
19
+
20
+ protected
21
+
22
+ def assign_names!(name)
23
+ @name = name
24
+ base_name, @class_path, @file_path, @class_nesting, @class_nesting_depth = extract_modules(@name)
25
+ @class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name)
26
+ if @class_nesting.empty?
27
+ @class_name = @class_name_without_nesting
28
+ else
29
+ @table_name = @class_nesting.underscore << "_" << @table_name
30
+ @class_name = "#{@class_nesting}::#{@class_name_without_nesting}"
31
+ end
32
+ end
33
+
34
+ # Extract modules from filesystem-style or ruby-style path:
35
+ # good/fun/stuff
36
+ # Good::Fun::Stuff
37
+ # produce the same results.
38
+ def extract_modules(name)
39
+ modules = name.include?('/') ? name.split('/') : name.split('::')
40
+ name = modules.pop
41
+ path = modules.map { |m| m.underscore }
42
+ file_path = (path + [name.underscore]).join('/')
43
+ nesting = modules.map { |m| m.camelize }.join('::')
44
+ [name, path, file_path, nesting, modules.size]
45
+ end
46
+
47
+ def inflect_names(name)
48
+ camel = name.camelize
49
+ under = camel.underscore
50
+ plural = under.pluralize
51
+ [camel, under, plural]
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,44 @@
1
+ # 'abstract' base class for ActiveMessaging processor classes
2
+ module ActiveMessaging
3
+
4
+ class Processor
5
+ include MessageSender
6
+
7
+ attr_reader :message
8
+
9
+ class<<self
10
+ def subscribes_to destination_name, headers={}
11
+ ActiveMessaging::Gateway.subscribe_to destination_name, self, headers
12
+ end
13
+ end
14
+
15
+ def logger()
16
+ @@logger ||= ActiveMessaging.logger
17
+ end
18
+
19
+ def on_message(message)
20
+ raise NotImplementedError.new("Implement the on_message method in your own processor class that extends ActiveMessaging::Processor")
21
+ end
22
+
23
+ def on_error(exception)
24
+ raise exception
25
+ end
26
+
27
+ # Bind the processor to the current message so that the processor could
28
+ # potentially access headers and other attributes of the message
29
+ def process!(message)
30
+ @message = message
31
+ return on_message(message.body)
32
+ rescue Object=>err
33
+ begin
34
+ on_error(err)
35
+ rescue ActiveMessaging::AbortMessageException => rpe
36
+ logger.error "Processor:process! - AbortMessageException caught."
37
+ raise rpe
38
+ rescue Object=>ex
39
+ logger.error "Processor:process! - error in on_error, will propagate no further: #{ex.message}\n\t#{ex.backtrace.join("\n\t")}"
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,26 @@
1
+ require 'logger'
2
+ require 'rails'
3
+ require 'activemessaging'
4
+
5
+ module ActiveMessaging
6
+ class Railtie < Rails::Railtie
7
+
8
+ initializer 'activemessaging.initialize' do
9
+
10
+ ActiveMessaging.load_activemessaging
11
+
12
+ if defined? Rails
13
+ ActiveMessaging.logger.info "ActiveMessaging: Rails available: Adding dispatcher prepare callback."
14
+ ActionDispatch::Callbacks.to_prepare do
15
+ ActiveMessaging.reload_activemessaging
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ rake_tasks do
22
+ load "tasks/start_consumers.rake"
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,189 @@
1
+ require 'test/unit'
2
+ #require "#{File.dirname(__FILE__)}/trace_filter"
3
+
4
+
5
+ module ActiveMessaging #:nodoc:
6
+ @@logger = nil
7
+
8
+ # def self.reload_activemessaging
9
+ # end
10
+
11
+ def self.logger
12
+ @@logger ||= MockLogger.new
13
+ @@logger
14
+ end
15
+
16
+ class AbortMessageException < Exception #:nodoc:
17
+ end
18
+
19
+ class StopFilterException < Exception #:nodoc:
20
+ end
21
+
22
+ class Gateway
23
+
24
+ def self.reset
25
+ unsubscribe
26
+ disconnect
27
+ @filters = []
28
+ @subscriptions = {}
29
+ @named_destinations = {}
30
+ @processor_groups = {}
31
+ @current_processor_group = nil
32
+ @connections = {}
33
+ end
34
+ end
35
+
36
+ module MessageSender
37
+
38
+ @@__a13g_initialized__ = false
39
+ def publish_with_reset(destination_name, message, headers={}, timeout=10)
40
+ unless @@__a13g_initialized__
41
+ ActiveMessaging.reload_activemessaging
42
+ @@__a13g_initialized__ = true
43
+ end
44
+ publish_without_reset(destination_name, message, headers, timeout)
45
+ end
46
+
47
+ alias_method_chain :publish, :reset
48
+
49
+ end
50
+
51
+ class TestMessage < ActiveMessaging::BaseMessage
52
+
53
+ def initialize(body="", headers={}, destination="")
54
+ super(body, nil, headers, destination)
55
+ @headers['destination'] = destination
56
+ end
57
+
58
+ end
59
+
60
+ module TestHelper
61
+
62
+ # #Many thanks must go to the ActiveRecord fixture code
63
+ # #for showing how to properly alias setup and teardown
64
+ # def self.included(base)
65
+ # base.extend(ClassMethods)
66
+ #
67
+ # class << base
68
+ # alias_method_chain :method_added, :a13g
69
+ # end
70
+ #
71
+ # end
72
+
73
+ # module ClassMethods
74
+ #
75
+ # def method_added_with_a13g(method)
76
+ # return if @__a13g_disable_method_added__
77
+ # @__a13g_disable_method_added__ = true
78
+ #
79
+ # case method.to_s
80
+ # when 'setup'
81
+ # unless method_defined?(:setup_without_a13g)
82
+ # alias_method :setup_without_a13g, :setup
83
+ # define_method(:full_setup) do
84
+ # setup_with_a13g
85
+ # setup_without_a13g
86
+ # end
87
+ # end
88
+ # alias_method :setup, :full_setup
89
+ # when 'teardown'
90
+ # unless method_defined?(:teardown_without_a13g)
91
+ # alias_method :teardown_without_a13g, :teardown
92
+ # define_method(:full_teardown) do
93
+ # teardown_without_a13g
94
+ # teardown_with_a13g
95
+ # end
96
+ # end
97
+ # alias_method :teardown, :full_teardown
98
+ # end
99
+ #
100
+ # method_added_without_a13g(method)
101
+ #
102
+ # @__a13g_disable_method_added__ = false
103
+ # end
104
+ #
105
+ # end
106
+
107
+ # def setup_with_a13g
108
+ # ActiveMessaging.reload_activemessaging
109
+ # end
110
+ #
111
+ # def teardown_with_a13g
112
+ # ActiveMessaging::Gateway.reset
113
+ # end
114
+
115
+ def mock_publish destination, body, publisher=nil, headers={}
116
+ ActiveMessaging::Gateway.publish destination, body, publisher, headers
117
+ end
118
+
119
+ def assert_message destination, body
120
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
121
+ error_message = <<-EOF
122
+ Message for '#{destination}' with '#{body}' is not present.
123
+ Messages:
124
+ #{ActiveMessaging::Gateway.connection('default').all_messages.inspect}
125
+ EOF
126
+ assert ActiveMessaging::Gateway.connection.find_message(destination, body), error_message
127
+ end
128
+
129
+ def assert_no_message_with destination, body
130
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
131
+ error_message = <<-EOF
132
+ Message for '#{destination}' with '#{body}' is present.
133
+ Messages:
134
+ #{ActiveMessaging::Gateway.connection('default').all_messages.inspect}
135
+ EOF
136
+ assert_nil ActiveMessaging::Gateway.connection('default').find_message(destination, body), error_message
137
+ end
138
+
139
+ def assert_no_messages destination
140
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
141
+ error_message = <<-EOF
142
+ Expected no messages.
143
+ Messages:
144
+ #{ActiveMessaging::Gateway.connection('default').all_messages.inspect}
145
+ EOF
146
+ assert_equal [], ActiveMessaging::Gateway.connection('default').all_messages, error_message
147
+ end
148
+
149
+ def assert_subscribed destination
150
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
151
+ error_message = <<-EOF
152
+ Not subscribed to #{destination}.
153
+ Subscriptions:
154
+ #{ActiveMessaging::Gateway.connection('default').subscriptions.inspect}
155
+ EOF
156
+ assert ActiveMessaging::Gateway.connection('default').find_subscription(destination), error_message
157
+ end
158
+
159
+ def assert_not_subscribed destination
160
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
161
+ error_message = <<-EOF
162
+ Subscribed to #{destination}.
163
+ Subscriptions:
164
+ #{ActiveMessaging::Gateway.connection('default').subscriptions.inspect}
165
+ EOF
166
+ assert_nil ActiveMessaging::Gateway.connection('default').find_subscription(destination), error_message
167
+ end
168
+
169
+ def assert_has_messages destination
170
+ destination_name = ActiveMessaging::Gateway.find_destination(destination).value
171
+ error_message = <<-EOF
172
+ No messages for #{destination_name}.
173
+ All messages:
174
+ #{ActiveMessaging::Gateway.connection('default').all_messages.inspect}
175
+ EOF
176
+ destination = ActiveMessaging::Gateway.connection('default').find_destination destination_name
177
+ assert !destination.nil? && !destination.messages.empty?, error_message
178
+ end
179
+ end
180
+
181
+ class MockLogger
182
+ def error(*args) ; end
183
+ def warn(*args) ; end
184
+ def info(*args) ; end
185
+ def debug(*args) ; end
186
+ end
187
+
188
+ end
189
+
@@ -0,0 +1,234 @@
1
+ # This owes no small debt to sidekiq for showing how to use celluloid for polling for messages.
2
+ # https://github.com/mperham/sidekiq/blob/poller/lib/sidekiq/manager.rb
3
+ if RUBY_VERSION.to_f >= 1.9 # Celluloid requires fibers support, which is not available on 1.8
4
+ require 'celluloid'
5
+
6
+ module ActiveMessaging
7
+
8
+ class ThreadedPoller
9
+
10
+ include Celluloid
11
+
12
+ # traps when any worker dies
13
+ trap_exit :died
14
+
15
+ attr_accessor :configuration, :receiver, :connection, :workers, :busy, :running, :pause
16
+
17
+ #
18
+ # connection is a string, name of the connection from broker.yml to use for this threaded poller instance
19
+ #
20
+ # configuration is a list of hashes
21
+ # each has describes a group of worker threads
22
+ # for each group, define what priorities those workers will process
23
+ # [
24
+ # {
25
+ # :pool_size => 1 # number of workers of this type
26
+ # :priorities => [1,2,3] # what message priorities this thread will process
27
+ # }
28
+ # ]
29
+ #
30
+ def initialize(connection='default', configuration={})
31
+ # default config is a pool size of 3 worker threads
32
+ self.configuration = configuration || [{:pool_size => 3}]
33
+ self.connection = connection
34
+ self.pause = 1
35
+ end
36
+
37
+ def start
38
+ logger.info "ActiveMessaging::ThreadedPoller start"
39
+
40
+ # these are workers ready to use
41
+ self.workers = []
42
+
43
+ # these are workers already working
44
+ self.busy = []
45
+
46
+ # this indicates if we are running or not, helps threads to stop gracefully
47
+ self.running = true
48
+
49
+ # subscribe will create the connections based on subscriptions in processsors
50
+ # (you can't find or use the connection until it is created by calling this)
51
+ ActiveMessaging::Gateway.subscribe
52
+
53
+ # create a message receiver actor, ony need one, using connection
54
+ receiver_connection = ActiveMessaging::Gateway.connection(connection)
55
+ self.receiver = MessageReceiver.new(current_actor, receiver_connection, pause)
56
+
57
+ # start the workers based on the config
58
+ configuration.each do |c|
59
+ (c[:pool_size] || 1).times{ self.workers << Worker.new_link(current_actor, c) }
60
+ end
61
+
62
+ # once all workers are created, start them up
63
+ self.workers.each{|worker| receive(worker)}
64
+
65
+ # in debug level, log info about workers every 10 seconds
66
+ log_status
67
+ end
68
+
69
+ def stop
70
+ logger.info "ActiveMessaging::ThreadedPoller stop"
71
+ # indicates to all busy workers not to pick up another messages, but does not interrupt
72
+ # also indicates to the message receiver to stop getting more messages
73
+ self.running = false
74
+
75
+ # tell each waiting worker to shut down. Running ones will be allowed to finish
76
+ receiver.terminate! if receiver.alive?
77
+ logger.info "ActiveMessaging::ThreadedPoller receiver terminated"
78
+
79
+ workers.each { |w| w.terminate! if w.alive? }
80
+ logger.info "ActiveMessaging::ThreadedPoller workers terminated"
81
+
82
+
83
+ after(0) { signal(:shutdown) } if stopped?
84
+ end
85
+
86
+ # recursive method, uses celluloid 'after' to keep calling
87
+ def log_status
88
+ return unless logger.debug?
89
+ logger.debug("ActiveMessaging::ThreadedPoller: conn:#{connection}, #{workers.count}, #{busy.count}, #{running}")
90
+ after(10){ log_status }
91
+ end
92
+
93
+ def receive(worker)
94
+ receiver.receive!(worker) if (receiver && running && worker)
95
+ end
96
+
97
+ def dispatch(message, worker)
98
+ workers.delete(worker)
99
+ busy << worker
100
+ worker.execute!(message)
101
+ end
102
+
103
+ def executed(worker)
104
+ busy.delete(worker)
105
+
106
+ if running
107
+ workers << worker
108
+ receive(worker)
109
+ else
110
+ worker.terminate if worker.alive?
111
+ if busy.empty?
112
+ logger.info "all executed: signal stopped"
113
+ after(0) { signal(:shutdown) }
114
+ end
115
+ end
116
+ end
117
+
118
+ def died(worker, reason)
119
+ busy.delete(worker)
120
+
121
+ if running
122
+ logger.info "uh oh, #{worker.inspect} died because of #{reason.class}"
123
+ worker = Worker.new_link(current_actor)
124
+ workers << worker
125
+ receive(worker)
126
+ else
127
+ logger.info "check to see if busy is empty: #{busy.inspect}"
128
+ if busy.empty?
129
+ logger.info "all died: signal stopped"
130
+ after(0){ signal(:shutdown) }
131
+ end
132
+ end
133
+ end
134
+
135
+ def stopped?
136
+ (!running && busy.empty?)
137
+ end
138
+
139
+ def inspect
140
+ "#<ThreadedPoller #{to_s}>"
141
+ end
142
+
143
+ def to_s
144
+ @str ||= "#{Process.pid}-#{Thread.current.object_id}:#{self.object_id}"
145
+ end
146
+
147
+ def logger; ActiveMessaging.logger; end
148
+
149
+ end
150
+
151
+ class MessageReceiver
152
+ include Celluloid
153
+
154
+ attr_accessor :poller, :connection, :pause
155
+
156
+ def initialize(poller, connection, pause=1)
157
+ logger.debug("MessageReceiver initialize: poller:#{poller}, connection:#{connection}, pause:#{pause}")
158
+
159
+ raise "No connection found for '#{poller.connection}'" unless connection
160
+
161
+ self.poller = poller
162
+ self.connection = connection
163
+ self.pause = pause
164
+ end
165
+
166
+ def receive(worker)
167
+ return unless poller.running
168
+
169
+ # logger.debug("***** MessageReceiver calling receive")
170
+ message = self.connection.receive(worker.options)
171
+ # logger.debug("***** MessageReceiver receive returned")
172
+
173
+ if message
174
+ logger.debug("ActiveMessaging::MessageReceiver.receive: message:'#{message.inspect}'")
175
+ poller.dispatch!(message, worker)
176
+ else
177
+ if (!poller || !poller.alive? || !poller.running)
178
+ logger.debug("ActiveMessaging::MessageReceiver.receive: terminate")
179
+ self.terminate
180
+ end
181
+ logger.debug("ActiveMessaging::MessageReceiver.receive: no message for worker #{worker.object_id}, retry in #{pause} sec")
182
+ after(pause) { receive(worker) }
183
+ end
184
+
185
+ end
186
+
187
+ def inspect
188
+ "#<MessageReceiver #{to_s}>"
189
+ end
190
+
191
+ def to_s
192
+ @str ||= "#{Process.pid}-#{Thread.current.object_id}:#{self.object_id}"
193
+ end
194
+
195
+ def logger; ::ActiveMessaging.logger; end
196
+ end
197
+
198
+ class Worker
199
+ include Celluloid
200
+
201
+ attr_accessor :poller, :options
202
+
203
+ def initialize(poller, options)
204
+ self.poller = poller
205
+ self.options = options
206
+ end
207
+
208
+ def execute(message)
209
+ begin
210
+ ::ActiveMessaging::Gateway.dispatch(message)
211
+ rescue Object => err
212
+ logger.error("ActiveMessaging::Worker.execute error - #{err.inspect}")
213
+ abort(err)
214
+ ensure
215
+ ::ActiveRecord::Base.clear_active_connections! if defined?(::ActiveRecord)
216
+ end
217
+
218
+ poller.executed!(current_actor)
219
+ end
220
+
221
+ def inspect
222
+ "#<Worker #{to_s}>"
223
+ end
224
+
225
+ def to_s
226
+ @str ||= "#{Process.pid}-#{Thread.current.object_id}:#{self.object_id}"
227
+ end
228
+
229
+ def logger; ::ActiveMessaging.logger; end
230
+
231
+ end
232
+
233
+ end
234
+ end # if RUBY_VERSION