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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +66 -0
  4. data/README.md +69 -3
  5. data/TODO.md +8 -0
  6. data/docs/Messaging_Layer_Properties.md +141 -0
  7. data/docs/Why_HTTP_is_a_bad_choice.md +20 -0
  8. data/docs/diagrams/Pattern -- Command.drawio +1 -0
  9. data/docs/diagrams/Pattern -- Event direct.drawio +1 -0
  10. data/docs/diagrams/Pattern -- Event with Queue.drawio +1 -0
  11. data/docs/diagrams/Pattern -- Event.drawio +1 -0
  12. data/docs/diagrams/Pattern -- Query.drawio +1 -0
  13. data/docs/img/pattern--command.png +0 -0
  14. data/docs/img/pattern--event-direct.png +0 -0
  15. data/docs/img/pattern--event-using-queue.png +0 -0
  16. data/docs/img/pattern--event.png +0 -0
  17. data/docs/img/pattern--query.png +0 -0
  18. data/examples/basic_event_listener.rb +35 -0
  19. data/examples/basic_request_processor.rb +38 -0
  20. data/examples/using_messaging_low.rb +59 -0
  21. data/examples/using_pure_adapter.rb +62 -0
  22. data/lib/mimi/messaging.rb +441 -92
  23. data/lib/mimi/messaging/adapters.rb +22 -0
  24. data/lib/mimi/messaging/adapters/base.rb +233 -0
  25. data/lib/mimi/messaging/adapters/memory.rb +147 -0
  26. data/lib/mimi/messaging/adapters/test.rb +50 -0
  27. data/lib/mimi/messaging/errors.rb +24 -12
  28. data/lib/mimi/messaging/json_serializer.rb +45 -0
  29. data/lib/mimi/messaging/message.rb +25 -65
  30. data/lib/mimi/messaging/version.rb +3 -1
  31. data/mimi-messaging.gemspec +25 -23
  32. metadata +34 -77
  33. data/lib/mimi/messaging/connection.rb +0 -182
  34. data/lib/mimi/messaging/listener.rb +0 -72
  35. data/lib/mimi/messaging/mock.rb +0 -13
  36. data/lib/mimi/messaging/mock/connection.rb +0 -153
  37. data/lib/mimi/messaging/mock/request.rb +0 -19
  38. data/lib/mimi/messaging/mock/request_processor.rb +0 -92
  39. data/lib/mimi/messaging/model.rb +0 -27
  40. data/lib/mimi/messaging/model_provider.rb +0 -100
  41. data/lib/mimi/messaging/msgpack/msgpack_ext.rb +0 -14
  42. data/lib/mimi/messaging/msgpack/type_packer.rb +0 -104
  43. data/lib/mimi/messaging/notification.rb +0 -35
  44. data/lib/mimi/messaging/provider.rb +0 -48
  45. data/lib/mimi/messaging/request.rb +0 -56
  46. data/lib/mimi/messaging/request_processor.rb +0 -216
  47. data/lib/mimi/messaging/request_processor/context.rb +0 -39
  48. data/lib/mimi/messaging/request_processor/dsl.rb +0 -121
  49. data/lib/tasks/console_ext.rake +0 -6
  50. 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
@@ -1,124 +1,473 @@
1
- require 'mimi/core'
2
- require 'mimi/logger'
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
- include Mimi::Core::Module
7
- include Mimi::Logger::Instance
8
-
9
- # key in the message headers that is used to pass context id
10
- CONTEXT_ID_KEY = 'c'.freeze
11
-
12
- default_options(
13
- require_files: 'app/messaging/**/*.rb',
14
- mq_host: 'localhost',
15
- mq_port: 5672,
16
- mq_username: nil,
17
- mq_password: nil,
18
- mq_vhost: nil
19
- )
20
-
21
- def self.module_path
22
- Pathname.new(__dir__).join('..').join('..').expand_path
23
- end
24
-
25
- def self.module_manifest
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
- }
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
- def self.configure(*)
47
- super
48
- connections << Mimi::Messaging::Connection.new(module_options)
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
- # @return [Array<Mimi::Messaging::Connection>]
78
+ # Returns the configured adapter
79
+ #
80
+ # @return [Mimi::Messaging::Adapter]
52
81
  #
53
- def self.connections
54
- @connections ||= []
82
+ def self.adapter
83
+ raise Error, "Mimi::Messaging adapter is not configured" unless @adapter
84
+
85
+ @adapter
55
86
  end
56
87
 
57
- # @return [Array<Class < Mimi::Messaging::RequestProcessor>]
88
+ # Returns the module configured options
89
+ #
90
+ # @return [Hash]
58
91
  #
59
- def self.request_processor_classes
60
- @request_processor_classes ||= []
92
+ def self.options
93
+ @options
61
94
  end
62
95
 
63
- # @param [Class < Mimi::Messaging::RequestProcessor]
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
- def self.register_request_processor_class(request_processor_class)
66
- request_processor_classes << request_processor_class
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
- # Selects the connection to be used for sending/receiving messages from/to given queue
140
+ # Stops the Messaging module
141
+ #
142
+ # Stops all currently registered message processors, unless :processors
143
+ # option is false.
70
144
  #
71
- # @param queue_name [String]
72
- # @return [Mimi::Messaging::Connection]
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
- def self.connection_for(queue_name)
75
- connection_for_queue = connections.select do |c|
76
- c.queue_prefix && (
77
- (c.queue_prefix.is_a?(String) && queue_name.start_with?(c.queue_prefix)) ||
78
- (c.queue_prefix.is_a?(Array) && c.queue_prefix.any? { |qp| queue_name.start_with?(qp) })
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.first
81
- return connection_for_queue if connection_for_queue
82
- connections.select { |c| c.queue_prefix.nil? }.first
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
- def self.post(queue_name, raw_message, params = {})
86
- connection_for(queue_name).post(queue_name, raw_message, params)
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
- def self.get(queue_name, raw_message, params = {})
90
- connection_for(queue_name).get(queue_name, raw_message, params)
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
- def self.broadcast(queue_name, raw_message, params = {})
94
- connection_for(queue_name).broadcast(queue_name, raw_message, params)
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
- def self.start
98
- Mimi.require_files(module_options[:require_files]) if module_options[:require_files]
99
- connections.each(&:start)
100
- request_processor_classes.each(&:start)
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
- def self.stop
105
- request_processor_classes.each(&:stop)
106
- connections.each(&:stop)
107
- super
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'