mimi-messaging 1.1.1 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/lib/mimi/messaging.rb +27 -13
- data/lib/mimi/messaging/adapters/base.rb +1 -1
- data/lib/mimi/messaging/adapters/memory.rb +43 -15
- data/lib/mimi/messaging/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 100b84c9fb56887c8eec1e80249ffbb67f064253
|
4
|
+
data.tar.gz: 57a5fa1bf3163053777ce68b0d2a6224bbc127ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c85f6047982af4c061e422c7bbbb6713b3bf9039b14ac0eef18e9f745e97f3b27737eb90c513a301e056404a1d4f026fb8571076c95ccddbad8d3cf369264270
|
7
|
+
data.tar.gz: f372f54633f37e4ef98879c1c307cee0c3846d295213ee7a1b5ab68017e688957affcc61ef409cb41bb51817abb9fe665d8bb51ddf96de302dbb963e6a007887
|
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
|
|
data/lib/mimi/messaging.rb
CHANGED
@@ -14,14 +14,25 @@ module Mimi
|
|
14
14
|
# Usage: [TBD]
|
15
15
|
#
|
16
16
|
module Messaging
|
17
|
-
#
|
18
|
-
# "[<name>.][...]<name>/<
|
19
|
-
# Where <name> consists of
|
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
|
-
|
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
|
@@ -185,7 +196,7 @@ module Mimi
|
|
185
196
|
# @return nil
|
186
197
|
#
|
187
198
|
def self.command(target, message = {}, opts = {})
|
188
|
-
raise ArgumentError, "Invalid target argument" unless
|
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
|
|
@@ -206,7 +217,7 @@ module Mimi
|
|
206
217
|
# @return [Hash]
|
207
218
|
#
|
208
219
|
def self.query(target, message = {}, opts = {})
|
209
|
-
raise ArgumentError, "Invalid target argument" unless
|
220
|
+
raise ArgumentError, "Invalid target argument" unless REQUEST_TARGET_REGEX.match(target)
|
210
221
|
raise ArgumentError, "Invalid message, Hash or Message is expected" unless message.is_a?(Hash)
|
211
222
|
raise Error, "Failed to send query, adapter is not started" unless started?(:adapter)
|
212
223
|
|
@@ -215,12 +226,12 @@ module Mimi
|
|
215
226
|
|
216
227
|
# Broadcasts the event with the given target
|
217
228
|
#
|
218
|
-
# @param target [String] "<topic
|
229
|
+
# @param target [String] "<topic>#<event_type>", e.g. "customers#created"
|
219
230
|
# @param message [Hash,Mimi::Messaging::Message]
|
220
231
|
# @param opts [Hash] additional options
|
221
232
|
#
|
222
233
|
def self.event(target, message = {}, opts = {})
|
223
|
-
raise ArgumentError, "Invalid target argument" unless
|
234
|
+
raise ArgumentError, "Invalid target argument" unless EVENT_TARGET_REGEX.match(target)
|
224
235
|
raise ArgumentError, "Invalid message, Hash or Message is expected" unless message.is_a?(Hash)
|
225
236
|
raise Error, "Failed to broadcast event, adapter is not started" unless started?(:adapter)
|
226
237
|
|
@@ -339,7 +350,7 @@ module Mimi
|
|
339
350
|
end
|
340
351
|
|
341
352
|
message_processor_params = {
|
342
|
-
type: :
|
353
|
+
type: :event_with_queue,
|
343
354
|
topic_name: topic_name,
|
344
355
|
queue_name: queue_name,
|
345
356
|
processor: processor,
|
@@ -441,24 +452,27 @@ module Mimi
|
|
441
452
|
end
|
442
453
|
private_class_method :start_message_processor
|
443
454
|
|
444
|
-
# Starts
|
455
|
+
# Starts all registered message processors at the adapter
|
445
456
|
#
|
446
457
|
def self.start_all_message_processors
|
447
458
|
message_processors.each { |p| start_message_processor(p) }
|
448
459
|
end
|
449
460
|
private_class_method :start_all_message_processors
|
450
461
|
|
451
|
-
# Stops
|
462
|
+
# Stops all registered message processors at the adapter
|
452
463
|
#
|
453
464
|
def self.stop_all_processors
|
454
465
|
log "#{self} stopping all message processors"
|
455
466
|
adapter.stop_all_processors
|
467
|
+
message_processors.each { |p| p[:started] = false }
|
456
468
|
end
|
457
469
|
private_class_method :stop_all_processors
|
458
470
|
|
459
|
-
#
|
471
|
+
# Deregisters all message processors
|
460
472
|
#
|
461
|
-
def self.
|
473
|
+
def self.unregister_all_processors
|
474
|
+
stop_all_processors
|
475
|
+
message_processors.replace([])
|
462
476
|
end
|
463
477
|
end # module Messaging
|
464
478
|
end # module Mimi
|
@@ -88,7 +88,7 @@ module Mimi
|
|
88
88
|
|
89
89
|
# Broadcasts the event with the given target
|
90
90
|
#
|
91
|
-
# @param target [String] "<topic
|
91
|
+
# @param target [String] "<topic>#<event_type>", e.g. "customers#created"
|
92
92
|
# @param message [Mimi::Messaging::Message]
|
93
93
|
# @param opts [Hash] additional options
|
94
94
|
#
|
@@ -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
|
-
|
28
|
-
dispatch_command(target,
|
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
|
-
|
34
|
-
response_serialized = dispatch_query(target,
|
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
|
-
|
40
|
-
dispatch_event(target,
|
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
|
-
|
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,
|
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
|
|
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.
|
4
|
+
version: 1.2.6
|
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-
|
11
|
+
date: 2019-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mimi-core
|