mimi-messaging 0.1.12 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +66 -0
- data/README.md +69 -3
- data/TODO.md +8 -0
- data/docs/Messaging_Layer_Properties.md +141 -0
- data/docs/Why_HTTP_is_a_bad_choice.md +20 -0
- data/docs/diagrams/Pattern -- Command.drawio +1 -0
- data/docs/diagrams/Pattern -- Event direct.drawio +1 -0
- data/docs/diagrams/Pattern -- Event with Queue.drawio +1 -0
- data/docs/diagrams/Pattern -- Event.drawio +1 -0
- data/docs/diagrams/Pattern -- Query.drawio +1 -0
- data/docs/img/pattern--command.png +0 -0
- data/docs/img/pattern--event-direct.png +0 -0
- data/docs/img/pattern--event-using-queue.png +0 -0
- data/docs/img/pattern--event.png +0 -0
- data/docs/img/pattern--query.png +0 -0
- data/examples/basic_event_listener.rb +35 -0
- data/examples/basic_request_processor.rb +38 -0
- data/examples/using_messaging_low.rb +59 -0
- data/examples/using_pure_adapter.rb +62 -0
- data/lib/mimi/messaging.rb +441 -92
- data/lib/mimi/messaging/adapters.rb +22 -0
- data/lib/mimi/messaging/adapters/base.rb +233 -0
- data/lib/mimi/messaging/adapters/memory.rb +147 -0
- data/lib/mimi/messaging/adapters/test.rb +50 -0
- data/lib/mimi/messaging/errors.rb +24 -12
- data/lib/mimi/messaging/json_serializer.rb +45 -0
- data/lib/mimi/messaging/message.rb +25 -65
- data/lib/mimi/messaging/version.rb +3 -1
- data/mimi-messaging.gemspec +25 -23
- metadata +34 -77
- data/lib/mimi/messaging/connection.rb +0 -182
- data/lib/mimi/messaging/listener.rb +0 -72
- data/lib/mimi/messaging/mock.rb +0 -13
- data/lib/mimi/messaging/mock/connection.rb +0 -153
- data/lib/mimi/messaging/mock/request.rb +0 -19
- data/lib/mimi/messaging/mock/request_processor.rb +0 -92
- data/lib/mimi/messaging/model.rb +0 -27
- data/lib/mimi/messaging/model_provider.rb +0 -100
- data/lib/mimi/messaging/msgpack/msgpack_ext.rb +0 -14
- data/lib/mimi/messaging/msgpack/type_packer.rb +0 -104
- data/lib/mimi/messaging/notification.rb +0 -35
- data/lib/mimi/messaging/provider.rb +0 -48
- data/lib/mimi/messaging/request.rb +0 -56
- data/lib/mimi/messaging/request_processor.rb +0 -216
- data/lib/mimi/messaging/request_processor/context.rb +0 -39
- data/lib/mimi/messaging/request_processor/dsl.rb +0 -121
- data/lib/tasks/console_ext.rake +0 -6
- data/lib/tasks/console_helpers.rb +0 -116
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# In this example we're going to use only the adapter for communication
|
5
|
+
# between several components.
|
6
|
+
#
|
7
|
+
require "mimi/messaging"
|
8
|
+
|
9
|
+
#
|
10
|
+
# Simplistic processor for command/query/event messages.
|
11
|
+
#
|
12
|
+
class HelloProcessor
|
13
|
+
def initialize(name)
|
14
|
+
@name = name
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"<#{@name}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
def call_command(method_name, message, _opts)
|
22
|
+
puts "#{self}: COMMAND #{method_name} #{message.to_h}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def call_query(method_name, message, _opts)
|
26
|
+
puts "#{self}: QUERY #{method_name} #{message.to_h}"
|
27
|
+
{ b: "hello" }
|
28
|
+
end
|
29
|
+
|
30
|
+
def call_event(method_name, message, _opts)
|
31
|
+
puts "#{self}: EVENT #{method_name} #{message.to_h}"
|
32
|
+
end
|
33
|
+
end # class HelloProcessor
|
34
|
+
|
35
|
+
adapter = Mimi::Messaging::Adapters::Memory.new
|
36
|
+
adapter.register_message_serializer(Mimi::Messaging::JsonSerializer)
|
37
|
+
adapter.start
|
38
|
+
|
39
|
+
adapter.start_request_processor("hello", HelloProcessor.new("A"))
|
40
|
+
adapter.start_request_processor("hello", HelloProcessor.new("B"))
|
41
|
+
adapter.start_request_processor("hello", HelloProcessor.new("C"))
|
42
|
+
|
43
|
+
adapter.start_event_processor("hello", HelloProcessor.new("D"))
|
44
|
+
adapter.start_event_processor("hello", HelloProcessor.new("E"))
|
45
|
+
adapter.start_event_processor("hello", HelloProcessor.new("F"))
|
46
|
+
|
47
|
+
adapter.start_event_processor_with_queue("hello", "event_queue", HelloProcessor.new("G"))
|
48
|
+
adapter.start_event_processor_with_queue("hello", "event_queue", HelloProcessor.new("H"))
|
49
|
+
adapter.start_event_processor_with_queue("hello", "event_queue", HelloProcessor.new("I"))
|
50
|
+
|
51
|
+
result = adapter.command("hello/world", a: 123)
|
52
|
+
puts "Response: #{result}"
|
53
|
+
puts
|
54
|
+
|
55
|
+
result = adapter.query("hello/world", b: 456)
|
56
|
+
puts "Response: #{result}"
|
57
|
+
puts
|
58
|
+
|
59
|
+
adapter.event("hello/world", c: 789)
|
60
|
+
puts
|
61
|
+
|
62
|
+
adapter.stop
|
data/lib/mimi/messaging.rb
CHANGED
@@ -1,124 +1,473 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mimi/core"
|
4
|
+
require_relative "messaging/adapters"
|
5
|
+
require_relative "messaging/errors"
|
6
|
+
require_relative "messaging/json_serializer"
|
7
|
+
require_relative "messaging/message"
|
8
|
+
require_relative "messaging/version"
|
3
9
|
|
4
10
|
module Mimi
|
11
|
+
#
|
12
|
+
# Mimi::Messaging implements a messaging layer of a microservice application.
|
13
|
+
#
|
14
|
+
# Usage: [TBD]
|
15
|
+
#
|
5
16
|
module Messaging
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
desc: 'RabbitMQ username',
|
37
|
-
default: nil
|
38
|
-
},
|
39
|
-
mq_password: {
|
40
|
-
desc: 'RabbitMQ password',
|
41
|
-
default: nil
|
42
|
-
}
|
43
|
-
}
|
17
|
+
# Request target validation pattern:
|
18
|
+
# "[<name>.][...]<name>/<name>"
|
19
|
+
# Where <name> consists of valid identifier characters: A-Za-z0-9_
|
20
|
+
#
|
21
|
+
# Example:
|
22
|
+
# "shop.orders/list"
|
23
|
+
#
|
24
|
+
REQUEST_TARGET_REGEX = %r{^((\w+)\.)*(\w+)\/(\w+)$}.freeze
|
25
|
+
|
26
|
+
# Event target validation pattern:
|
27
|
+
# "[<name>.][...]<name>#<name>"
|
28
|
+
# Where <name> consists of valid identifier characters: A-Za-z0-9_
|
29
|
+
#
|
30
|
+
# Example:
|
31
|
+
# "shop.orders#created"
|
32
|
+
#
|
33
|
+
EVENT_TARGET_REGEX = %r{^((\w+)\.)*(\w+)\#(\w+)$}.freeze
|
34
|
+
|
35
|
+
# By default Mimi::Messaging logs at given level
|
36
|
+
DEFAULT_LOG_AT_LEVEL = :info
|
37
|
+
|
38
|
+
#
|
39
|
+
# Configure up the Messaging module
|
40
|
+
#
|
41
|
+
# Sets up Messaging layer dependencies configuration, e.g.
|
42
|
+
# configures logger, message serializer etc.
|
43
|
+
#
|
44
|
+
def self.use(options)
|
45
|
+
@serializer = options[:serializer] if options.key?(:serializer)
|
46
|
+
@logger = options[:logger] if options.key?(:logger)
|
44
47
|
end
|
45
48
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
# Configure the Messaging layer
|
50
|
+
#
|
51
|
+
# Configures the adapter (type) and the adapter specific options.
|
52
|
+
#
|
53
|
+
# @param options [Hash] options passed to the adapter
|
54
|
+
# @option options [String,Symbol] :mq_adapter Adapter type, one of "memory", "test" etc
|
55
|
+
#
|
56
|
+
def self.configure(options)
|
57
|
+
raise ArgumentError, "Hash is expected as options" unless options.is_a?(Hash)
|
58
|
+
raise ConfigurationError, ":mq_adapter is expected to be set" unless options.key?(:mq_adapter)
|
59
|
+
|
60
|
+
@options = options.dup
|
61
|
+
adapter_name = options[:mq_adapter].to_s
|
62
|
+
adapter_class = Mimi::Messaging::Adapters.registered_adapters[adapter_name]
|
63
|
+
unless adapter_class
|
64
|
+
registered_adapter_names = Mimi::Messaging::Adapters.registered_adapters.keys
|
65
|
+
raise(
|
66
|
+
ConfigurationError,
|
67
|
+
"Failed to find adapter with name '#{adapter_name}', " \
|
68
|
+
" registered adapters are: #{registered_adapter_names.join(', ')}"
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
@adapter = adapter_class.new(@options)
|
73
|
+
raise ConfigurationError, "Message serializer is not registered" unless @serializer
|
74
|
+
|
75
|
+
@adapter.register_message_serializer(@serializer)
|
49
76
|
end
|
50
77
|
|
51
|
-
#
|
78
|
+
# Returns the configured adapter
|
79
|
+
#
|
80
|
+
# @return [Mimi::Messaging::Adapter]
|
52
81
|
#
|
53
|
-
def self.
|
54
|
-
|
82
|
+
def self.adapter
|
83
|
+
raise Error, "Mimi::Messaging adapter is not configured" unless @adapter
|
84
|
+
|
85
|
+
@adapter
|
55
86
|
end
|
56
87
|
|
57
|
-
#
|
88
|
+
# Returns the module configured options
|
89
|
+
#
|
90
|
+
# @return [Hash]
|
58
91
|
#
|
59
|
-
def self.
|
60
|
-
@
|
92
|
+
def self.options
|
93
|
+
@options
|
61
94
|
end
|
62
95
|
|
63
|
-
#
|
96
|
+
# Starts the Messaging module
|
97
|
+
#
|
98
|
+
# Starts the adapter if it is not started yet, and registers
|
99
|
+
# the current message serializer with it. Starting the adapter opens connections
|
100
|
+
# with a message broker.
|
101
|
+
#
|
102
|
+
# Automatically starts all currently registered message processors, unless
|
103
|
+
# the :processors option is false.
|
64
104
|
#
|
65
|
-
|
66
|
-
|
105
|
+
# Example:
|
106
|
+
# # to only start the adapter, so that we can send messages,
|
107
|
+
# # but not process incoming messages:
|
108
|
+
# Mimi::Messaging.start(processors: false)
|
109
|
+
#
|
110
|
+
# # to start everything
|
111
|
+
# Mimi::Messaging.start
|
112
|
+
#
|
113
|
+
# @param params [Hash] additional parameters
|
114
|
+
# @option params [true,false] :adapter (default: true)
|
115
|
+
# start the adapter
|
116
|
+
# @option params [true,false] :processors (default: true)
|
117
|
+
# automatically registers message processors
|
118
|
+
#
|
119
|
+
def self.start(params = {})
|
120
|
+
adapter # ensures that adapter is configured
|
121
|
+
log("#{name} starting with adapter '#{options[:mq_adapter]}'")
|
122
|
+
params = { # defaults
|
123
|
+
adapter: true,
|
124
|
+
processors: true
|
125
|
+
}.merge(params)
|
126
|
+
|
127
|
+
if !started?(:adapter) && params[:adapter]
|
128
|
+
adapter.start
|
129
|
+
started!(:adapter)
|
130
|
+
end
|
131
|
+
|
132
|
+
if !started?(:processors) && params[:processors]
|
133
|
+
start_all_message_processors
|
134
|
+
started!(:processors)
|
135
|
+
end
|
136
|
+
|
137
|
+
true
|
67
138
|
end
|
68
139
|
|
69
|
-
#
|
140
|
+
# Stops the Messaging module
|
141
|
+
#
|
142
|
+
# Stops all currently registered message processors, unless :processors
|
143
|
+
# option is false.
|
70
144
|
#
|
71
|
-
#
|
72
|
-
#
|
145
|
+
# Stops the adapter, unless :adapter option is false. Stopping the adapter
|
146
|
+
# closes connections with a message broker.
|
147
|
+
#
|
148
|
+
# Example:
|
149
|
+
# # to start everything
|
150
|
+
# Mimi::Messaging.start
|
151
|
+
#
|
152
|
+
# # to only stop the message processors, so that we can send messages
|
153
|
+
# # but not process incoming messages:
|
154
|
+
# Mimi::Messaging.stop(adapter: false, processors: true)
|
155
|
+
#
|
156
|
+
# # to stop everything
|
157
|
+
# Mimi::Messaging.stop
|
158
|
+
#
|
159
|
+
# @param params [Hash] additional parameters
|
160
|
+
# @option params [true,false] :processors (default: true)
|
161
|
+
# deregister all message processors
|
162
|
+
# @option params [true,false] :adapter (default: true)
|
163
|
+
# deregister all message processors
|
164
|
+
#
|
165
|
+
def self.stop(params = {})
|
166
|
+
params = { # defaults
|
167
|
+
adapter: true,
|
168
|
+
processors: true
|
169
|
+
}.merge(params)
|
170
|
+
|
171
|
+
if params[:processors]
|
172
|
+
stop_all_processors
|
173
|
+
started!(:processors, false)
|
174
|
+
end
|
175
|
+
|
176
|
+
if params[:adapter]
|
177
|
+
adapter.stop # TODO: stopping adapter without stopping processors? TBD
|
178
|
+
started!(:adapter, false)
|
179
|
+
end
|
180
|
+
|
181
|
+
log("#{name} stopped")
|
182
|
+
true
|
183
|
+
end
|
184
|
+
|
185
|
+
# Sends the command to the given target
|
186
|
+
#
|
187
|
+
# Example:
|
188
|
+
# Mimi::Messaging.command("users/create", name: "John Smith")
|
189
|
+
#
|
190
|
+
# @param target [String] "<queue>/<method>"
|
191
|
+
# @param message [Hash,Mimi::Messaging::Message]
|
192
|
+
# @param opts [Hash] additional adapter-specific options
|
193
|
+
#
|
194
|
+
# @return nil
|
195
|
+
#
|
196
|
+
def self.command(target, message = {}, opts = {})
|
197
|
+
raise ArgumentError, "Invalid target argument" unless REQUEST_TARGET_REGEX.match(target)
|
198
|
+
raise ArgumentError, "Invalid message, Hash or Message is expected" unless message.is_a?(Hash)
|
199
|
+
raise Error, "Failed to send command, adapter is not started" unless started?(:adapter)
|
200
|
+
|
201
|
+
adapter.command(target, Mimi::Messaging::Message.new(message), opts)
|
202
|
+
end
|
203
|
+
|
204
|
+
# Executes the query to the given target and returns response
|
205
|
+
#
|
206
|
+
# Raises Timeout::Error if the response from the target was not received in time.
|
207
|
+
#
|
208
|
+
# Example:
|
209
|
+
# result = Mimi::Messaging.query("users/find", id: 157)
|
210
|
+
#
|
211
|
+
# @param target [String] "<queue>/<method>"
|
212
|
+
# @param message [Hash,Mimi::Messaging::Message]
|
213
|
+
# @param opts [Hash] additional options, e.g. :timeout
|
214
|
+
#
|
215
|
+
# @return [Hash]
|
216
|
+
#
|
217
|
+
def self.query(target, message = {}, opts = {})
|
218
|
+
raise ArgumentError, "Invalid target argument" unless REQUEST_TARGET_REGEX.match(target)
|
219
|
+
raise ArgumentError, "Invalid message, Hash or Message is expected" unless message.is_a?(Hash)
|
220
|
+
raise Error, "Failed to send query, adapter is not started" unless started?(:adapter)
|
221
|
+
|
222
|
+
adapter.query(target, Mimi::Messaging::Message.new(message), opts)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Broadcasts the event with the given target
|
226
|
+
#
|
227
|
+
# @param target [String] "<topic>#<event_type>", e.g. "customers#created"
|
228
|
+
# @param message [Hash,Mimi::Messaging::Message]
|
229
|
+
# @param opts [Hash] additional options
|
230
|
+
#
|
231
|
+
def self.event(target, message = {}, opts = {})
|
232
|
+
raise ArgumentError, "Invalid target argument" unless EVENT_TARGET_REGEX.match(target)
|
233
|
+
raise ArgumentError, "Invalid message, Hash or Message is expected" unless message.is_a?(Hash)
|
234
|
+
raise Error, "Failed to broadcast event, adapter is not started" unless started?(:adapter)
|
235
|
+
|
236
|
+
adapter.event(target, Mimi::Messaging::Message.new(message), opts)
|
237
|
+
end
|
238
|
+
|
239
|
+
# Registers the request (command/query) processor.
|
73
240
|
#
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
241
|
+
# If the adapter and the processors are started, the processor
|
242
|
+
# will be automatically started (registered with the adapter).
|
243
|
+
#
|
244
|
+
# Processor must respond to #call_command() AND #call_query()
|
245
|
+
# which accepts 3 arguments: (method, message, opts).
|
246
|
+
#
|
247
|
+
# TBD: It must #ack! or #nack! the message.
|
248
|
+
#
|
249
|
+
# If the processor raises an error, the message will be NACK-ed and accepted again
|
250
|
+
# at a later time.
|
251
|
+
#
|
252
|
+
# @param queue_name [String] "<queue>"
|
253
|
+
# @param processor [#call_command()]
|
254
|
+
# @param opts [Hash] additional adapter-specific options
|
255
|
+
#
|
256
|
+
def self.register_request_processor(queue_name, processor, opts = {})
|
257
|
+
# validates processor
|
258
|
+
unless (
|
259
|
+
processor.respond_to?(:call_command) && processor.method(:call_command).arity >= 3 &&
|
260
|
+
processor.respond_to?(:call_query) && processor.method(:call_query).arity >= 3
|
261
|
+
)
|
262
|
+
raise(
|
263
|
+
ArgumentError,
|
264
|
+
"Invalid request processor passed to .register_request_processor(), " \
|
265
|
+
"expected to respond to #call_command(...) AND #call_query(method_name, request, opts)"
|
266
|
+
)
|
267
|
+
end
|
268
|
+
|
269
|
+
message_processor_params = {
|
270
|
+
type: :request,
|
271
|
+
queue_name: queue_name,
|
272
|
+
processor: processor,
|
273
|
+
opts: opts.dup,
|
274
|
+
started: false
|
275
|
+
}
|
276
|
+
if started?(:adapter) && started?(:processors)
|
277
|
+
start_message_processor(message_processor_params)
|
278
|
+
end
|
279
|
+
message_processors << message_processor_params
|
280
|
+
end
|
281
|
+
|
282
|
+
# Registers an event processor without a queue
|
283
|
+
#
|
284
|
+
# If the adapter and the processors are started, the processor
|
285
|
+
# will be automatically started (registered with the adapter).
|
286
|
+
#
|
287
|
+
# Processor must respond to #call_event() which accepts 3 arguments:
|
288
|
+
# (method, message, opts).
|
289
|
+
#
|
290
|
+
# TBD: It must #ack! or #nack! the message.
|
291
|
+
#
|
292
|
+
# If the processor raises an error, the message will be NACK-ed and accepted again
|
293
|
+
# at a later time.
|
294
|
+
#
|
295
|
+
# @param topic_name [String] "<topic>"
|
296
|
+
# @param processor [#call_event()]
|
297
|
+
# @param opts [Hash] additional adapter-specific options
|
298
|
+
#
|
299
|
+
def self.register_event_processor(topic_name, processor, opts = {})
|
300
|
+
# validates processor
|
301
|
+
if !processor.respond_to?(:call_event) || processor.method(:call_event).arity < 3
|
302
|
+
raise(
|
303
|
+
ArgumentError,
|
304
|
+
"Invalid event processor passed to .register_event_processor(), " \
|
305
|
+
"expected to respond to #call_event(method_name, request, opts)"
|
79
306
|
)
|
80
|
-
end
|
81
|
-
|
82
|
-
|
307
|
+
end
|
308
|
+
|
309
|
+
message_processor_params = {
|
310
|
+
type: :event,
|
311
|
+
topic_name: topic_name,
|
312
|
+
processor: processor,
|
313
|
+
opts: opts.dup,
|
314
|
+
started: false
|
315
|
+
}
|
316
|
+
if started?(:adapter) && started?(:processors)
|
317
|
+
start_message_processor(message_processor_params)
|
318
|
+
end
|
319
|
+
message_processors << message_processor_params
|
320
|
+
end
|
321
|
+
|
322
|
+
# Registers an event processor with a queue
|
323
|
+
#
|
324
|
+
# If the adapter and the processors are started, the processor
|
325
|
+
# will be automatically started (registered with the adapter).
|
326
|
+
#
|
327
|
+
# Processor must respond to #call_event() which accepts 3 arguments:
|
328
|
+
# (method, message, opts).
|
329
|
+
#
|
330
|
+
# TBD: It must #ack! or #nack! the message.
|
331
|
+
#
|
332
|
+
# If the processor raises an error, the message will be NACK-ed and accepted again
|
333
|
+
# at a later time.
|
334
|
+
#
|
335
|
+
# @param topic_name [String] "<topic>"
|
336
|
+
# @param queue_name [String] "<queue>"
|
337
|
+
# @param processor [#call_event()]
|
338
|
+
# @param opts [Hash] additional adapter-specific options
|
339
|
+
#
|
340
|
+
def self.register_event_processor_with_queue(topic_name, queue_name, processor, opts = {})
|
341
|
+
# validates processor
|
342
|
+
if !processor.respond_to?(:call_event) || processor.method(:call_event).arity < 3
|
343
|
+
raise(
|
344
|
+
ArgumentError,
|
345
|
+
"Invalid event processor passed to .register_event_processor_with_queue(), " \
|
346
|
+
"expected to respond to #call_event(method_name, request, opts)"
|
347
|
+
)
|
348
|
+
end
|
349
|
+
|
350
|
+
message_processor_params = {
|
351
|
+
type: :event,
|
352
|
+
topic_name: topic_name,
|
353
|
+
queue_name: queue_name,
|
354
|
+
processor: processor,
|
355
|
+
opts: opts.dup,
|
356
|
+
started: false
|
357
|
+
}
|
358
|
+
if started?(:adapter) && started?(:processors)
|
359
|
+
start_message_processor(message_processor_params)
|
360
|
+
end
|
361
|
+
message_processors << message_processor_params
|
362
|
+
end
|
363
|
+
|
364
|
+
# private-ish methods below
|
365
|
+
# Not a part of the end-user API, but still accessible by other components
|
366
|
+
|
367
|
+
# Returns configured logger
|
368
|
+
#
|
369
|
+
# @return [Logger] or compatible
|
370
|
+
#
|
371
|
+
def self.logger
|
372
|
+
@logger
|
373
|
+
end
|
374
|
+
|
375
|
+
# Logs with configured logger at configured logging level
|
376
|
+
#
|
377
|
+
# @param message [String]
|
378
|
+
#
|
379
|
+
def self.log(message)
|
380
|
+
return unless logger
|
381
|
+
|
382
|
+
log_at_level = options[:mq_log_at_level] || DEFAULT_LOG_AT_LEVEL
|
383
|
+
log_at_level = log_at_level.to_sym
|
384
|
+
return if log_at_level == :none
|
385
|
+
|
386
|
+
logger.send(log_at_level, message)
|
387
|
+
end
|
388
|
+
|
389
|
+
# Returns true if the given subsystem started
|
390
|
+
#
|
391
|
+
# Example:
|
392
|
+
# started?(:adapter)
|
393
|
+
#
|
394
|
+
# @param name [Symbol]
|
395
|
+
# @return [true,false]
|
396
|
+
#
|
397
|
+
def self.started?(name)
|
398
|
+
@started ||= {}
|
399
|
+
@started[name]
|
83
400
|
end
|
401
|
+
private_class_method :started?
|
84
402
|
|
85
|
-
|
86
|
-
|
403
|
+
# Sets the state of the given subsystem
|
404
|
+
#
|
405
|
+
# Example:
|
406
|
+
# started!(:adapter, false)
|
407
|
+
#
|
408
|
+
# @param name [Symbol]
|
409
|
+
# @param value [true,false] (default: true)
|
410
|
+
#
|
411
|
+
def self.started!(name, value = true)
|
412
|
+
@started ||= {}
|
413
|
+
@started[name] = !!value
|
87
414
|
end
|
415
|
+
private_class_method :started!
|
88
416
|
|
89
|
-
|
90
|
-
|
417
|
+
# Returns the set of registered message processors
|
418
|
+
#
|
419
|
+
# @return [Array{Hash}]
|
420
|
+
#
|
421
|
+
def self.message_processors
|
422
|
+
@message_processors ||= []
|
91
423
|
end
|
424
|
+
private_class_method :message_processors
|
425
|
+
|
426
|
+
# Starts the message processor at the configured and started adapter
|
427
|
+
#
|
428
|
+
# @param message_processor_params [Hash]
|
429
|
+
#
|
430
|
+
def self.start_message_processor(message_processor_params)
|
431
|
+
return if message_processor_params[:started] # do not start processor twice
|
92
432
|
|
93
|
-
|
94
|
-
|
433
|
+
p = message_processor_params
|
434
|
+
case p[:type]
|
435
|
+
when :request
|
436
|
+
log "#{self} starting request processor #{p[:processor]}@#{p[:queue_name]}"
|
437
|
+
adapter.start_request_processor(p[:queue_name], p[:processor], p[:opts])
|
438
|
+
when :event
|
439
|
+
log "#{self} starting event processor #{p[:processor]}@#{p[:topic_name]}"
|
440
|
+
adapter.start_event_processor(p[:topic_name], p[:processor], p[:opts])
|
441
|
+
when :event_with_queue
|
442
|
+
log "#{self} starting event processor #{p[:processor]}@#{p[:topic_name]}/#{p[:queue_name]}"
|
443
|
+
adapter.start_event_processor_with_queue(
|
444
|
+
p[:topic_name], p[:queue_name], p[:processor], p[:opts]
|
445
|
+
)
|
446
|
+
else
|
447
|
+
raise "Unexpected message processor type: #{message_processor[:type].inspect}"
|
448
|
+
end
|
449
|
+
message_processor_params[:started] = true
|
95
450
|
end
|
451
|
+
private_class_method :start_message_processor
|
96
452
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
super
|
453
|
+
# Starts (registers) all message processors
|
454
|
+
#
|
455
|
+
def self.start_all_message_processors
|
456
|
+
message_processors.each { |p| start_message_processor(p) }
|
102
457
|
end
|
458
|
+
private_class_method :start_all_message_processors
|
103
459
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
460
|
+
# Stops (deregisters) all message processors
|
461
|
+
#
|
462
|
+
def self.stop_all_processors
|
463
|
+
log "#{self} stopping all message processors"
|
464
|
+
adapter.stop_all_processors
|
465
|
+
end
|
466
|
+
private_class_method :stop_all_processors
|
467
|
+
|
468
|
+
# Resets the internal state, private
|
469
|
+
#
|
470
|
+
def self.reset
|
108
471
|
end
|
109
472
|
end # module Messaging
|
110
473
|
end # module Mimi
|
111
|
-
|
112
|
-
require_relative 'messaging/version'
|
113
|
-
require_relative 'messaging/errors'
|
114
|
-
require_relative 'messaging/connection'
|
115
|
-
require_relative 'messaging/message'
|
116
|
-
require_relative 'messaging/request'
|
117
|
-
require_relative 'messaging/request_processor'
|
118
|
-
require_relative 'messaging/provider'
|
119
|
-
require_relative 'messaging/model'
|
120
|
-
require_relative 'messaging/model_provider'
|
121
|
-
require_relative 'messaging/notification'
|
122
|
-
require_relative 'messaging/listener'
|
123
|
-
require_relative 'messaging/msgpack/type_packer'
|
124
|
-
require_relative 'messaging/msgpack/msgpack_ext'
|