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