mimi-messaging 1.1.0 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 54a536d257b3a394b605e80e1b24167e5912f785
4
- data.tar.gz: 03374246a36903692068863563ec7a111cd18b8b
3
+ metadata.gz: b8baee68b3135998131486589ca0fc56b3454c5e
4
+ data.tar.gz: 469dc284417b30a83c13a84b7035076cefc8dc64
5
5
  SHA512:
6
- metadata.gz: '0295bb31beb00e6370340e4db43bab2a145e9d463d514bcdf1eba944a171edb614133afc7384a9e1e3010b832c4ff4b547ae9a27e307efb19d4abe3acee0782d'
7
- data.tar.gz: 5e3a7f512fc58d688551c9601c26b863872dfeafaf860554796f2493ba30234045c591520c453fa973cae529069516cc19653553cf369eca7f31bc7c5ac29395
6
+ metadata.gz: cfab8d964275ca42ce5334212e95bde2808bc0874390bea45602f906c4cf5c7e05cc60d25d3a198a6ee7c6b1935fbfd7416480429cedce5104a8ad8f26f7a5de
7
+ data.tar.gz: 66d91dcf023f0255384bee9805f0228a445f48109ba751b57d16d38a8798535cfe01dee459a40be41af6c3d6f1711a87c8c4894bc4fca2c007c037f6be28aa0f
data/README.md CHANGED
@@ -57,7 +57,7 @@ there are several available adapters:
57
57
  * [Kafka](https://github.com/kukushkin/mimi-messaging-kafka)
58
58
  * RabbitMQ (TBD)
59
59
  * NATS (TBD)
60
- * Amazon SQS/SNS
60
+ * [Amazon SQS/SNS](https://github.com/kukushkin/mimi-messaging-sqs_sns)
61
61
  * in-memory (single process)
62
62
 
63
63
  ## Designing apps
@@ -65,10 +65,11 @@ there are several available adapters:
65
65
 
66
66
  There are only two hard problems in distributed systems:
67
67
 
68
+ ```
68
69
  2. Exactly-once delivery
69
70
  1. Guaranteed order of messages
70
71
  2. Exactly-once delivery
71
-
72
+ ```
72
73
 
73
74
  ## License
74
75
 
@@ -14,14 +14,25 @@ module Mimi
14
14
  # Usage: [TBD]
15
15
  #
16
16
  module Messaging
17
- # Target validation pattern:
18
- # "[<name>.][...]<name>/<name>"
19
- # Where <name> consists of valid identifier characters: A-Za-z0-9_
17
+ # Request target validation pattern:
18
+ # "[<name>.][...]<name>/<identifier>"
19
+ # Where <name> consists of characters: A-Za-z0-9_-
20
+ # and <method_name> can be any of: A-Za-z0-9_
20
21
  #
21
22
  # Example:
22
23
  # "shop.orders/list"
23
24
  #
24
- TARGET_REGEX = %r{^((\w+)\.)*(\w+)\/(\w+)$}.freeze
25
+ REQUEST_TARGET_REGEX = %r{^([\w\-]+\.)*([\w\-]+)\/(\w+)$}.freeze
26
+
27
+ # Event target validation pattern:
28
+ # "[<name>.][...]<name>#<identifier>"
29
+ # Where <name> consists of characters: A-Za-z0-9_-
30
+ # and <method_name> can be any of: A-Za-z0-9_
31
+ #
32
+ # Example:
33
+ # "shop.orders#created"
34
+ #
35
+ EVENT_TARGET_REGEX = %r{^([\w\-]+\.)*([\w\-]+)\#(\w+)$}.freeze
25
36
 
26
37
  # By default Mimi::Messaging logs at given level
27
38
  DEFAULT_LOG_AT_LEVEL = :info
@@ -179,13 +190,13 @@ module Mimi
179
190
  # Mimi::Messaging.command("users/create", name: "John Smith")
180
191
  #
181
192
  # @param target [String] "<queue>/<method>"
182
- # @param message [Hash]
193
+ # @param message [Hash,Mimi::Messaging::Message]
183
194
  # @param opts [Hash] additional adapter-specific options
184
195
  #
185
196
  # @return nil
186
197
  #
187
198
  def self.command(target, message = {}, opts = {})
188
- raise ArgumentError, "Invalid target argument" unless TARGET_REGEX.match(target)
199
+ raise ArgumentError, "Invalid target argument" unless REQUEST_TARGET_REGEX.match(target)
189
200
  raise ArgumentError, "Invalid message, Hash or Message is expected" unless message.is_a?(Hash)
190
201
  raise Error, "Failed to send command, adapter is not started" unless started?(:adapter)
191
202
 
@@ -196,6 +207,9 @@ module Mimi
196
207
  #
197
208
  # Raises Timeout::Error if the response from the target was not received in time.
198
209
  #
210
+ # Example:
211
+ # result = Mimi::Messaging.query("users/find", id: 157)
212
+ #
199
213
  # @param target [String] "<queue>/<method>"
200
214
  # @param message [Hash,Mimi::Messaging::Message]
201
215
  # @param opts [Hash] additional options, e.g. :timeout
@@ -203,7 +217,7 @@ module Mimi
203
217
  # @return [Hash]
204
218
  #
205
219
  def self.query(target, message = {}, opts = {})
206
- raise ArgumentError, "Invalid target argument" unless TARGET_REGEX.match(target)
220
+ raise ArgumentError, "Invalid target argument" unless REQUEST_TARGET_REGEX.match(target)
207
221
  raise ArgumentError, "Invalid message, Hash or Message is expected" unless message.is_a?(Hash)
208
222
  raise Error, "Failed to send query, adapter is not started" unless started?(:adapter)
209
223
 
@@ -212,12 +226,12 @@ module Mimi
212
226
 
213
227
  # Broadcasts the event with the given target
214
228
  #
215
- # @param target [String] "<topic>/<event_type>", e.g. "customers/created"
216
- # @param message [Hash]
229
+ # @param target [String] "<topic>#<event_type>", e.g. "customers#created"
230
+ # @param message [Hash,Mimi::Messaging::Message]
217
231
  # @param opts [Hash] additional options
218
232
  #
219
233
  def self.event(target, message = {}, opts = {})
220
- raise ArgumentError, "Invalid target argument" unless TARGET_REGEX.match(target)
234
+ raise ArgumentError, "Invalid target argument" unless EVENT_TARGET_REGEX.match(target)
221
235
  raise ArgumentError, "Invalid message, Hash or Message is expected" unless message.is_a?(Hash)
222
236
  raise Error, "Failed to broadcast event, adapter is not started" unless started?(:adapter)
223
237
 
@@ -450,6 +464,7 @@ module Mimi
450
464
  def self.stop_all_processors
451
465
  log "#{self} stopping all message processors"
452
466
  adapter.stop_all_processors
467
+ message_processors.each { |p| p[:started] = false }
453
468
  end
454
469
  private_class_method :stop_all_processors
455
470
 
@@ -63,7 +63,7 @@ module Mimi
63
63
  # Sends the command to the given target
64
64
  #
65
65
  # @param target [String] "<queue>/<method>"
66
- # @param message [Hash]
66
+ # @param message [Mimi::Messaging::Message]
67
67
  # @param opts [Hash] additional options
68
68
  #
69
69
  # @return nil
@@ -76,7 +76,7 @@ module Mimi
76
76
  # Executes the query to the given target and returns response
77
77
  #
78
78
  # @param target [String] "<queue>/<method>"
79
- # @param message [Hash]
79
+ # @param message [Mimi::Messaging::Message]
80
80
  # @param opts [Hash] additional options, e.g. :timeout
81
81
  #
82
82
  # @return [Hash]
@@ -88,8 +88,8 @@ module Mimi
88
88
 
89
89
  # Broadcasts the event with the given target
90
90
  #
91
- # @param target [String] "<topic>/<event_type>", e.g. "customers/created"
92
- # @param message [Hash]
91
+ # @param target [String] "<topic>#<event_type>", e.g. "customers#created"
92
+ # @param message [Mimi::Messaging::Message]
93
93
  # @param opts [Hash] additional options
94
94
  #
95
95
  def event(_target, _message, _opts = {})
@@ -124,7 +124,7 @@ module Mimi
124
124
  raise(
125
125
  ArgumentError,
126
126
  "Invalid request processor passed to #{self.class}##{__method__}(), " \
127
- "expected to respond to #call_command(...) AND #call_query(method_name, request, opts)"
127
+ "expected to respond to #call_command(method_name, message, opts) AND #call_query(...)"
128
128
  )
129
129
  end
130
130
 
@@ -149,7 +149,7 @@ module Mimi
149
149
  raise(
150
150
  ArgumentError,
151
151
  "Invalid event processor passed to #{self.class}##{__method__}(), " \
152
- "expected to respond to #call_event(method_name, request, opts)"
152
+ "expected to respond to #call_event(event_type, message, opts)"
153
153
  )
154
154
  end
155
155
 
@@ -175,7 +175,7 @@ module Mimi
175
175
  raise(
176
176
  ArgumentError,
177
177
  "Invalid event processor passed to #{self.class}##{__method__}(), " \
178
- "expected to respond to #call_event(method_name, request, opts)"
178
+ "expected to respond to #call_event(event_type, message, opts)"
179
179
  )
180
180
  end
181
181
 
@@ -23,21 +23,39 @@ module Mimi
23
23
  def stop
24
24
  end
25
25
 
26
+ # Sends COMMAND to target
27
+ #
28
+ # @param target [String]
29
+ # @param message [Mimi::Messaging::Message]
30
+ # @param opts [Hash]
31
+ #
26
32
  def command(target, message, opts = {})
27
- message_serialized = serialize(message)
28
- dispatch_command(target, message_serialized, opts)
33
+ raise ArgumentError, "Message is expected" unless message.is_a?(Mimi::Messaging::Message)
34
+ dispatch_command(target, message, opts)
29
35
  nil
30
36
  end
31
37
 
38
+ # Sends QUERY to target
39
+ #
40
+ # @param target [String]
41
+ # @param message [Mimi::Messaging::Message]
42
+ # @param opts [Hash]
43
+ #
32
44
  def query(target, message, opts = {})
33
- message_serialized = serialize(message)
34
- response_serialized = dispatch_query(target, message_serialized, opts)
45
+ raise ArgumentError, "Message is expected" unless message.is_a?(Mimi::Messaging::Message)
46
+ response_serialized = dispatch_query(target, message, opts)
35
47
  deserialize(response_serialized)
36
48
  end
37
49
 
50
+ # Sends EVENT to target
51
+ #
52
+ # @param target [String]
53
+ # @param message [Mimi::Messaging::Message]
54
+ # @param opts [Hash]
55
+ #
38
56
  def event(target, message, opts = {})
39
- message_serialized = serialize(message)
40
- dispatch_event(target, message_serialized, opts)
57
+ raise ArgumentError, "Message is expected" unless message.is_a?(Mimi::Messaging::Message)
58
+ dispatch_event(target, message, opts)
41
59
  end
42
60
 
43
61
  def start_request_processor(queue_name, processor, _opts = {})
@@ -67,38 +85,48 @@ module Mimi
67
85
 
68
86
  private
69
87
 
70
- def dispatch_command(target, message_serialized, _opts = {})
88
+ # Simulates a transmitted message, following serialization/deserialization:
89
+ # message out -> message in
90
+ #
91
+ # @param message [Mimi::Messaging::Message]
92
+ # @return [Mimi::Messaging::Message]
93
+ #
94
+ def transmitted_message(message)
95
+ Mimi::Messaging::Message.new(
96
+ deserialize(serialize(message)),
97
+ message.headers
98
+ )
99
+ end
100
+
101
+ def dispatch_command(target, message, _opts = {})
71
102
  queue_name, method_name = target.split("/")
72
- message = deserialize(message_serialized)
73
103
  return unless request_processors[queue_name]
74
104
 
75
105
  # pick random processor serving the target
76
106
  processor = request_processors[queue_name].sample
77
- processor.call_command(method_name, message, {})
107
+ processor.call_command(method_name, transmitted_message(message), {})
78
108
  end
79
109
 
80
- def dispatch_query(target, message_serialized, _opts = {})
110
+ def dispatch_query(target, message, _opts = {})
81
111
  queue_name, method_name = target.split("/")
82
- message = deserialize(message_serialized)
83
112
  raise Timeout::Error unless request_processors[queue_name]
84
113
 
85
114
  # pick random processor serving the target
86
115
  processor = request_processors[queue_name].sample
87
- response = processor.call_query(method_name, message, {})
116
+ response = processor.call_query(method_name, transmitted_message(message), {})
88
117
  serialize(response)
89
118
  end
90
119
 
91
120
  def dispatch_event(target, message_serialized, _opts = {})
92
- topic_name, event_type = target.split("/")
121
+ topic_name, event_type = target.split("#")
93
122
  processors = event_processors[topic_name] || []
94
123
  processor_queues = event_processors_with_queue[topic_name] || {}
95
124
  processor_queues.values.each do |same_queue_processors|
96
125
  processors << same_queue_processors.sample
97
126
  end
98
127
 
99
- message = deserialize(message_serialized)
100
128
  processors.each do |processor|
101
- processor.call_event(event_type, message, {})
129
+ processor.call_event(event_type, transmitted_message(message), {})
102
130
  end
103
131
  end
104
132
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Mimi
4
4
  module Messaging
5
- VERSION = "1.1.0"
5
+ VERSION = "1.2.4"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mimi-messaging
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Kukushkin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-08 00:00:00.000000000 Z
11
+ date: 2019-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mimi-core