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