mimi-messaging 0.1.9 → 1.1.0

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 +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'