mimi-messaging 0.1.12 → 1.0.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 +428 -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/version.rb +3 -1
  30. data/mimi-messaging.gemspec +25 -23
  31. metadata +34 -78
  32. data/lib/mimi/messaging/connection.rb +0 -182
  33. data/lib/mimi/messaging/listener.rb +0 -72
  34. data/lib/mimi/messaging/message.rb +0 -74
  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,460 @@
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/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
- 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
- }
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
- def self.configure(*)
47
- super
48
- connections << Mimi::Messaging::Connection.new(module_options)
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
- # @return [Array<Mimi::Messaging::Connection>]
68
+ # Returns the configured adapter
69
+ #
70
+ # @return [Mimi::Messaging::Adapter]
52
71
  #
53
- def self.connections
54
- @connections ||= []
72
+ def self.adapter
73
+ raise Error, "Mimi::Messaging adapter is not configured" unless @adapter
74
+
75
+ @adapter
55
76
  end
56
77
 
57
- # @return [Array<Class < Mimi::Messaging::RequestProcessor>]
78
+ # Returns the module configured options
79
+ #
80
+ # @return [Hash]
58
81
  #
59
- def self.request_processor_classes
60
- @request_processor_classes ||= []
82
+ def self.options
83
+ @options
61
84
  end
62
85
 
63
- # @param [Class < Mimi::Messaging::RequestProcessor]
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
- def self.register_request_processor_class(request_processor_class)
66
- request_processor_classes << request_processor_class
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
- # Selects the connection to be used for sending/receiving messages from/to given queue
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
- # @param queue_name [String]
72
- # @return [Mimi::Messaging::Connection]
231
+ # Processor must respond to #call_command() AND #call_query()
232
+ # which accepts 3 arguments: (method, message, opts).
73
233
  #
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) })
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.first
81
- return connection_for_queue if connection_for_queue
82
- connections.select { |c| c.queue_prefix.nil? }.first
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
- def self.post(queue_name, raw_message, params = {})
86
- connection_for(queue_name).post(queue_name, raw_message, params)
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
- def self.get(queue_name, raw_message, params = {})
90
- connection_for(queue_name).get(queue_name, raw_message, params)
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
- def self.broadcast(queue_name, raw_message, params = {})
94
- connection_for(queue_name).broadcast(queue_name, raw_message, params)
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
- 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
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
- def self.stop
105
- request_processor_classes.each(&:stop)
106
- connections.each(&:stop)
107
- super
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'