moleculer 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +30 -6
- data/Gemfile.lock +15 -15
- data/README.md +42 -11
- data/Rakefile +1 -1
- data/lib/moleculer/broker.rb +52 -11
- data/lib/moleculer/configuration.rb +67 -11
- data/lib/moleculer/node.rb +3 -3
- data/lib/moleculer/packets/base.rb +41 -9
- data/lib/moleculer/packets/discover.rb +7 -0
- data/lib/moleculer/packets/event.rb +5 -3
- data/lib/moleculer/packets/heartbeat.rb +4 -5
- data/lib/moleculer/packets/info.rb +19 -16
- data/lib/moleculer/packets/req.rb +23 -40
- data/lib/moleculer/packets/res.rb +3 -3
- data/lib/moleculer/registry.rb +13 -7
- data/lib/moleculer/serializers/json.rb +3 -2
- data/lib/moleculer/service/action.rb +3 -6
- data/lib/moleculer/service/base.rb +35 -5
- data/lib/moleculer/service/event.rb +2 -4
- data/lib/moleculer/support/open_struct.rb +2 -2
- data/lib/moleculer/transporters/fake.rb +8 -2
- data/lib/moleculer/transporters/redis.rb +8 -7
- data/lib/moleculer/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a334a18ec4219854cfaf70d634adab755d0dc07cf4ed0e284e9762915e8518a
|
4
|
+
data.tar.gz: 59c11268ac5f85d9afb825d6f621f29aac1b793852621196645bc7a8150b38e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b32dad21bf85fba69d66e9c65296f6e39dab9f3d44eea5a473b48456fdeb362b9b0723456356ce6cf58dfa8c0a5ca0582b4ad7522d4e44f52eeddda1f242b58
|
7
|
+
data.tar.gz: 9bef8d267905857f6b3144ccd33dfa7e5335603d59993bc9654755fc0887b0832168d545494b951b0fb168a30878aff42b757dd8a06f63e3c1a5171fdd6ae7a0
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
|
-
|
1
|
+
## 0.3.0
|
2
|
+
### Breaking Changes
|
3
|
+
* `rescue_event` and `rescue_action` have been removed and replaced with a more generic `rescue_from`
|
4
|
+
handler
|
5
|
+
|
6
|
+
### Features
|
7
|
+
* adds version support
|
8
|
+
* `log_level`, `transporter`, `heartbeat_interval`, `log_file` and `timeout` are now configurable
|
9
|
+
via environment variable prefixed with `MOLECULER_`
|
10
|
+
* added `rescue_from` configuration. this replaces `rescue_event` and `rescue_action`.
|
11
|
+
* updated json to 2.2.0
|
12
|
+
* updated oj to 3.7.12
|
13
|
+
* updated redis to 4.1.2
|
14
|
+
* updated yard to 0.9.20
|
15
|
+
* updated rspec-support to 3.8.2
|
16
|
+
* updated ruby-progressbar to 1.10.1
|
17
|
+
* updated rspec-mocks to 3.8.1
|
18
|
+
* updated simplecov to 0.17.0
|
19
|
+
* updated rspec-core to 3.8.2
|
20
|
+
* updated rubocop to 0.74.0
|
21
|
+
|
22
|
+
### Bugfixes
|
23
|
+
* fix `concurrent_ruby` version requirement to ensure at least `1.1` is required.
|
24
|
+
* fixes issue where services don't recognize heartbeats by firing a DISCOVER packet
|
25
|
+
when a heartbeat is received from an unknown node.
|
26
|
+
|
27
|
+
## 0.2.0
|
28
|
+
* add a fake transporter that can be used for testing without dependencies on an
|
29
|
+
* add `rescue_action` and `rescue_event` rescue handlers
|
2
30
|
|
31
|
+
## 0.1.1
|
3
32
|
### Features
|
4
33
|
|
5
34
|
* **actions:** ability to process errors that occur when executing actions
|
@@ -13,8 +42,3 @@
|
|
13
42
|
* fix `concurrent_ruby` version requirement to ensure at least `1.1` is required
|
14
43
|
* fix an issue where heartbeats back up in the queue and cause errors when consumed
|
15
44
|
|
16
|
-
# 0.1.1
|
17
|
-
|
18
|
-
### Bugfixes
|
19
|
-
* fixes bug where event publishing uses the wrong method name to look up local events
|
20
|
-
* fixes condition where events may double publish when multiple events are registered
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
moleculer (0.
|
4
|
+
moleculer (0.3.0)
|
5
5
|
awesome_print (~> 1.8)
|
6
6
|
concurrent-ruby (~> 1.1)
|
7
7
|
ougai (~> 1.7)
|
@@ -13,10 +13,10 @@ GEM
|
|
13
13
|
awesome_print (1.8.0)
|
14
14
|
concurrent-ruby (1.1.5)
|
15
15
|
diff-lcs (1.3)
|
16
|
-
docile (1.3.
|
17
|
-
jaro_winkler (1.5.
|
18
|
-
json (2.
|
19
|
-
oj (3.
|
16
|
+
docile (1.3.2)
|
17
|
+
jaro_winkler (1.5.3)
|
18
|
+
json (2.2.0)
|
19
|
+
oj (3.8.1)
|
20
20
|
ougai (1.7.1)
|
21
21
|
oj (~> 3.4)
|
22
22
|
parallel (1.17.0)
|
@@ -24,36 +24,36 @@ GEM
|
|
24
24
|
ast (~> 2.4.0)
|
25
25
|
rainbow (3.0.0)
|
26
26
|
rake (10.5.0)
|
27
|
-
redis (4.
|
27
|
+
redis (4.1.2)
|
28
28
|
rspec (3.8.0)
|
29
29
|
rspec-core (~> 3.8.0)
|
30
30
|
rspec-expectations (~> 3.8.0)
|
31
31
|
rspec-mocks (~> 3.8.0)
|
32
|
-
rspec-core (3.8.
|
32
|
+
rspec-core (3.8.2)
|
33
33
|
rspec-support (~> 3.8.0)
|
34
|
-
rspec-expectations (3.8.
|
34
|
+
rspec-expectations (3.8.4)
|
35
35
|
diff-lcs (>= 1.2.0, < 2.0)
|
36
36
|
rspec-support (~> 3.8.0)
|
37
|
-
rspec-mocks (3.8.
|
37
|
+
rspec-mocks (3.8.1)
|
38
38
|
diff-lcs (>= 1.2.0, < 2.0)
|
39
39
|
rspec-support (~> 3.8.0)
|
40
|
-
rspec-support (3.8.
|
41
|
-
rubocop (0.
|
40
|
+
rspec-support (3.8.2)
|
41
|
+
rubocop (0.74.0)
|
42
42
|
jaro_winkler (~> 1.5.1)
|
43
43
|
parallel (~> 1.10)
|
44
44
|
parser (>= 2.6)
|
45
45
|
rainbow (>= 2.2.2, < 4.0)
|
46
46
|
ruby-progressbar (~> 1.7)
|
47
47
|
unicode-display_width (>= 1.4.0, < 1.7)
|
48
|
-
ruby-progressbar (1.10.
|
49
|
-
simplecov (0.
|
48
|
+
ruby-progressbar (1.10.1)
|
49
|
+
simplecov (0.17.0)
|
50
50
|
docile (~> 1.1)
|
51
51
|
json (>= 1.8, < 3)
|
52
52
|
simplecov-html (~> 0.10.0)
|
53
53
|
simplecov-html (0.10.2)
|
54
54
|
timecop (0.9.1)
|
55
55
|
unicode-display_width (1.6.0)
|
56
|
-
yard (0.9.
|
56
|
+
yard (0.9.20)
|
57
57
|
|
58
58
|
PLATFORMS
|
59
59
|
ruby
|
@@ -70,4 +70,4 @@ DEPENDENCIES
|
|
70
70
|
yard (~> 0.9.11)
|
71
71
|
|
72
72
|
BUNDLED WITH
|
73
|
-
1.17.
|
73
|
+
1.17.3
|
data/README.md
CHANGED
@@ -20,7 +20,7 @@ gem install "moleculer-ruby"
|
|
20
20
|
or add to your Gemfile:
|
21
21
|
|
22
22
|
```ruby
|
23
|
-
gem "moleculer-ruby", "~>0.
|
23
|
+
gem "moleculer-ruby", "~>0.3"
|
24
24
|
```
|
25
25
|
|
26
26
|
### Create a Simple Service
|
@@ -55,17 +55,36 @@ Moleculer.configure do |c|
|
|
55
55
|
end
|
56
56
|
```
|
57
57
|
|
58
|
+
Some Moleculer configuration values can also be set through environment variables.
|
59
|
+
|
58
60
|
### Configuration Options
|
59
61
|
|
60
|
-
####
|
61
|
-
Sets
|
62
|
+
#### rescue_from
|
63
|
+
Sets an error handler that ties into the infrastructure of Moleculer instructing it how to handle errors of the specified
|
64
|
+
class. This allows things like Airbrake to easily tie in to exception handling. By default Moleculer rescues from
|
65
|
+
`StandardError` and simply logs it out.
|
66
|
+
|
67
|
+
#### log_file (default: STDOUT)
|
68
|
+
Sets the moleculer log_file. This value can also be set by setting the `MOLECULER_LOG_FILE` environment variable.
|
69
|
+
|
70
|
+
#### logger
|
71
|
+
Sets the moleculer logger. The logger must be an instance of `Moleculer::Support::LogProxy`. The log proxy supports any
|
72
|
+
ruby logger that supports the ruby `Logger` interface.
|
73
|
+
|
74
|
+
Example:
|
75
|
+
```
|
76
|
+
c.logger = Moleculer::Support::Logger.new(Rails.logger)
|
77
|
+
```
|
78
|
+
|
79
|
+
In the case that the logger is set to something other than the default, the log level set for moleculer is ignored, and the
|
80
|
+
level of the passed logger is used.
|
62
81
|
|
63
82
|
#### log_level (default: debug)
|
64
83
|
Sets the log level of the node. defaults to `:debug`. Can be one of `:trace`, `:debug`, `:info`, `:warn`, `:error`,
|
65
|
-
`:fatal`.
|
84
|
+
`:fatal`. This value can also be set by setting the `MOLECULER_LOG_LEVEL` environment variable.
|
66
85
|
|
67
86
|
#### heartbeat_interval (default: 5)
|
68
|
-
The interval in which to send heartbeats.
|
87
|
+
The interval in which to send heartbeats. This value can also be set by setting the `MOLECULER_HEARTBEAT` environment variable.
|
69
88
|
|
70
89
|
#### node_id (default: \<hostname\>-\<pid\>)
|
71
90
|
The node id. Node IDs are required to be unique. In Moleculer-ruby all node ids are suffixed with the PID of the
|
@@ -82,10 +101,11 @@ service whose `service_name` is set to `users` would get the full `service_name`
|
|
82
101
|
|
83
102
|
#### timeout (default: 5)
|
84
103
|
The Moleculer system timeout. This is used to determine how long a moleculer `call` will wait for a response until it
|
85
|
-
times out and throws an error.
|
104
|
+
times out and throws an error. This value can also be set by setting the `MOLECULER_TIMEOUT` environment variable.
|
86
105
|
|
87
106
|
#### transporter (default: redis://localhost)
|
88
107
|
The transporter Moleculer should use. For more information on transporters see [Transporters](https://moleculer.services/docs/0.13/networking.html#Transporters)
|
108
|
+
This value can also be set by setting the `MOLECULER_TRANSPORTER` environment variable.
|
89
109
|
|
90
110
|
|
91
111
|
## Roadmap
|
@@ -98,11 +118,22 @@ Initial release
|
|
98
118
|
* Service registry & dynamic service discovery
|
99
119
|
* JSON serializer
|
100
120
|
|
101
|
-
### 0.2 (
|
121
|
+
### 0.2 (COMPLETE)
|
102
122
|
* Fake transporter (for testing)
|
103
123
|
* Error handling, (ability to use Airbrake, etc.)
|
104
|
-
* Event grouping
|
105
124
|
|
106
|
-
### 0.3 (
|
107
|
-
*
|
108
|
-
*
|
125
|
+
### 0.3 (COMPLETE)
|
126
|
+
* Service versioning
|
127
|
+
* Environment variable based configuration
|
128
|
+
|
129
|
+
### 0.4 (IN PROGRESS)
|
130
|
+
* Protobuf serializer
|
131
|
+
* Add MessagePack serializer
|
132
|
+
* Circuit Breaker support
|
133
|
+
* Retry support
|
134
|
+
|
135
|
+
### 0.5 (PLANNED)
|
136
|
+
* Bulkhead support
|
137
|
+
* Fallback support
|
138
|
+
* Nested call support
|
139
|
+
|
data/Rakefile
CHANGED
data/lib/moleculer/broker.rb
CHANGED
@@ -14,7 +14,7 @@ module Moleculer
|
|
14
14
|
class Broker
|
15
15
|
include Moleculer::Support
|
16
16
|
extend Forwardable
|
17
|
-
attr_reader :config
|
17
|
+
attr_reader :config, :logger
|
18
18
|
|
19
19
|
def_delegators :@config, :node_id, :heartbeat_interval, :services, :service_prefix
|
20
20
|
|
@@ -93,6 +93,7 @@ module Moleculer
|
|
93
93
|
|
94
94
|
def start
|
95
95
|
@logger.info "starting"
|
96
|
+
@logger.info "using transporter '#{@config.transporter}'"
|
96
97
|
@transporter.start
|
97
98
|
register_local_node
|
98
99
|
start_subscribers
|
@@ -128,7 +129,7 @@ module Moleculer
|
|
128
129
|
def process_message(channel, message)
|
129
130
|
subscribers[channel] << Packets.for(channel.split(".")[1]).new(message) if subscribers[channel]
|
130
131
|
rescue StandardError => e
|
131
|
-
|
132
|
+
config.handle_error(e)
|
132
133
|
end
|
133
134
|
|
134
135
|
def process_response(packet)
|
@@ -142,7 +143,7 @@ module Moleculer
|
|
142
143
|
|
143
144
|
events.each { |e| e.execute(packet.data, self) }
|
144
145
|
rescue StandardError => e
|
145
|
-
|
146
|
+
config.handle_error(e)
|
146
147
|
end
|
147
148
|
|
148
149
|
def process_request(packet)
|
@@ -194,7 +195,7 @@ module Moleculer
|
|
194
195
|
end
|
195
196
|
|
196
197
|
def publish(packet_type, message = {})
|
197
|
-
packet = Packets.for(packet_type).new(message.merge(sender: @registry.local_node.id))
|
198
|
+
packet = Packets.for(packet_type).new(@config, message.merge(sender: @registry.local_node.id))
|
198
199
|
@transporter.publish(packet)
|
199
200
|
end
|
200
201
|
|
@@ -203,20 +204,36 @@ module Moleculer
|
|
203
204
|
end
|
204
205
|
|
205
206
|
def publish_heartbeat
|
207
|
+
@logger.trace "publishing hearbeat"
|
206
208
|
publish(:heartbeat)
|
207
209
|
end
|
208
210
|
|
209
211
|
##
|
210
212
|
# Publishes the discover packet
|
211
213
|
def publish_discover
|
214
|
+
@logger.trace "publishing discover request"
|
212
215
|
publish(:discover)
|
213
216
|
end
|
214
217
|
|
215
|
-
|
216
|
-
|
218
|
+
##
|
219
|
+
# Publish targeted discovery to node
|
220
|
+
def publish_discover_to_node_id(node_id)
|
221
|
+
publish_to_node_id(:discover, node_id)
|
222
|
+
end
|
217
223
|
|
218
|
-
|
219
|
-
|
224
|
+
##
|
225
|
+
# Publishes the info packet to either all nodes, or the given node
|
226
|
+
def publish_info(node_id = nil, force = false)
|
227
|
+
return publish(:info, @registry.local_node.to_h) unless node_id
|
228
|
+
|
229
|
+
node = @registry.safe_fetch_node(node_id)
|
230
|
+
if node
|
231
|
+
publish_to_node(:info, node, @registry.local_node.to_h)
|
232
|
+
elsif force
|
233
|
+
## in rare cases there may be a lack of synchronization between brokers, if we can't find the node in the
|
234
|
+
# registry we will attempt to force publish it (if force is true)
|
235
|
+
publish_to_node_id(:info, node_id, @registry.local_node.to_h)
|
236
|
+
end
|
220
237
|
end
|
221
238
|
|
222
239
|
def publish_req(request_data)
|
@@ -228,7 +245,14 @@ module Moleculer
|
|
228
245
|
end
|
229
246
|
|
230
247
|
def publish_to_node(packet_type, node, message = {})
|
231
|
-
packet = Packets.for(packet_type).new(message.merge(node: node))
|
248
|
+
packet = Packets.for(packet_type).new(@config, message.merge(node: node))
|
249
|
+
@transporter.publish(packet)
|
250
|
+
end
|
251
|
+
|
252
|
+
##
|
253
|
+
# Publishes the provided packet directly to the given node_id
|
254
|
+
def publish_to_node_id(packet_type, node_id, message = {})
|
255
|
+
packet = Packets.for(packet_type).new(@config, message.merge(node_id: node_id))
|
232
256
|
@transporter.publish(packet)
|
233
257
|
end
|
234
258
|
|
@@ -259,6 +283,7 @@ module Moleculer
|
|
259
283
|
end
|
260
284
|
|
261
285
|
def start_heartbeat
|
286
|
+
@logger.trace "starting heartbeat timer"
|
262
287
|
Concurrent::TimerTask.new(execution_interval: heartbeat_interval) do
|
263
288
|
publish_heartbeat
|
264
289
|
@registry.expire_nodes
|
@@ -276,12 +301,14 @@ module Moleculer
|
|
276
301
|
end
|
277
302
|
|
278
303
|
def subscribe_to_events
|
304
|
+
@logger.info "setting up 'EVENT' subscriber"
|
279
305
|
subscribe("MOL.EVENT.#{node_id}") do |packet|
|
280
306
|
process_event(packet)
|
281
307
|
end
|
282
308
|
end
|
283
309
|
|
284
310
|
def subscribe_to_info
|
311
|
+
@logger.trace "setting up 'INFO' subscribers"
|
285
312
|
subscribe("MOL.INFO.#{node_id}") do |packet|
|
286
313
|
register_or_update_remote_node(packet)
|
287
314
|
end
|
@@ -291,34 +318,48 @@ module Moleculer
|
|
291
318
|
end
|
292
319
|
|
293
320
|
def subscribe_to_res
|
321
|
+
@logger.trace "setting up 'RES' subscriber"
|
294
322
|
subscribe("MOL.RES.#{node_id}") do |packet|
|
295
323
|
process_response(packet)
|
296
324
|
end
|
297
325
|
end
|
298
326
|
|
299
327
|
def subscribe_to_req
|
328
|
+
@logger.trace "setting up 'REQ' subscriber"
|
300
329
|
subscribe("MOL.REQ.#{node_id}") do |packet|
|
301
330
|
process_request(packet)
|
302
331
|
end
|
303
332
|
end
|
304
333
|
|
305
334
|
def subscribe_to_discover
|
335
|
+
@logger.trace "setting up 'DISCOVER' subscriber"
|
306
336
|
subscribe("MOL.DISCOVER") do |packet|
|
307
337
|
publish_info(packet.sender) unless packet.sender == node_id
|
308
338
|
end
|
309
339
|
subscribe("MOL.DISCOVER.#{node_id}") do |packet|
|
310
|
-
publish_info(packet.sender)
|
340
|
+
publish_info(packet.sender, true)
|
311
341
|
end
|
312
342
|
end
|
313
343
|
|
344
|
+
##
|
345
|
+
# Subscribes to heartbeats from other services. If a node is not registered when it received a heartbeat the broker
|
346
|
+
# will send a discover packet directly to the node that published the beat.
|
314
347
|
def subscribe_to_heartbeat
|
348
|
+
@logger.trace "setting up 'HEARTBEAT' subscriber"
|
315
349
|
subscribe("MOL.HEARTBEAT") do |packet|
|
316
350
|
node = @registry.safe_fetch_node(packet.sender)
|
317
|
-
node
|
351
|
+
if node
|
352
|
+
node.beat
|
353
|
+
else
|
354
|
+
# because the node is not registered with the broker, we have to assume that something broke down. we need to
|
355
|
+
# force a publish to the node we just received the heartbeat from
|
356
|
+
publish_discover_to_node_id(packet.sender)
|
357
|
+
end
|
318
358
|
end
|
319
359
|
end
|
320
360
|
|
321
361
|
def subscribe_to_disconnect
|
362
|
+
@logger.trace "setting up 'DISCONNECT' subscriber"
|
322
363
|
subscribe("MOL.DISCONNECT") do |packet|
|
323
364
|
@registry.remove_node(packet.sender)
|
324
365
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moleculer
|
2
4
|
##
|
3
5
|
# Handles Moleculer configuration
|
@@ -48,11 +50,11 @@ module Moleculer
|
|
48
50
|
@accessors ||= {}
|
49
51
|
@accessors[attribute.to_sym] = { default: default, block: block }
|
50
52
|
|
51
|
-
class_eval <<-
|
53
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
52
54
|
def #{attribute}
|
53
55
|
@#{attribute} ||= default_for("#{attribute}".to_sym)
|
54
56
|
end
|
55
|
-
|
57
|
+
METHOD
|
56
58
|
|
57
59
|
instance_eval do
|
58
60
|
attr_writer attribute.to_sym
|
@@ -60,29 +62,34 @@ module Moleculer
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
|
-
config_accessor :log_file
|
64
|
-
config_accessor :log_level, :debug
|
65
65
|
config_accessor :logger do |c|
|
66
66
|
logger = Ougai::Logger.new(c.log_file || STDOUT)
|
67
67
|
logger.formatter = Ougai::Formatters::Readable.new("MOL")
|
68
68
|
logger.level = c.log_level
|
69
69
|
Moleculer::Support::LogProxy.new(logger)
|
70
70
|
end
|
71
|
-
config_accessor :
|
72
|
-
config_accessor :
|
73
|
-
config_accessor :
|
71
|
+
config_accessor :log_file, ENV["MOLECULER_LOG_FILE"]
|
72
|
+
config_accessor :log_level, ENV["MOLECULER_LOG_LEVEL"]&.to_sym || :debug
|
73
|
+
config_accessor :heartbeat_interval, ENV["MOLECULER_HEARTBEAT_INTERVAL"]&.to_i || 5
|
74
|
+
config_accessor :timeout, ENV["MOLECULER_TIMEOUT"]&.to_i || 5
|
75
|
+
config_accessor :transporter, ENV["MOLECULER_TRANSPORTER"] || "redis://localhost"
|
76
|
+
|
74
77
|
config_accessor :serializer, :json
|
75
78
|
config_accessor :node_id, "#{Socket.gethostname.downcase}-#{Process.pid}"
|
79
|
+
|
76
80
|
config_accessor :service_prefix
|
77
|
-
config_accessor :rescue_action
|
78
|
-
config_accessor :rescue_event
|
79
81
|
|
80
82
|
attr_accessor :broker
|
81
83
|
|
82
|
-
def initialize(options={})
|
84
|
+
def initialize(options = {})
|
83
85
|
options.each do |option, value|
|
84
86
|
send("#{option}=".to_sym, value)
|
85
87
|
end
|
88
|
+
@rescue_handlers = {}
|
89
|
+
|
90
|
+
rescue_from(StandardError) do |e|
|
91
|
+
logger.error(e)
|
92
|
+
end
|
86
93
|
end
|
87
94
|
|
88
95
|
def services
|
@@ -91,11 +98,60 @@ module Moleculer
|
|
91
98
|
|
92
99
|
def services=(array)
|
93
100
|
@services = ServiceList.new(self)
|
94
|
-
array.each { |s| @services << s}
|
101
|
+
array.each { |s| @services << s }
|
102
|
+
end
|
103
|
+
|
104
|
+
def to_h
|
105
|
+
{
|
106
|
+
log_file: log_file,
|
107
|
+
log_level: log_level,
|
108
|
+
heartbeat_interval: heartbeat_interval,
|
109
|
+
timeout: timeout,
|
110
|
+
transporter: transporter,
|
111
|
+
serializer: serializer,
|
112
|
+
node_id: node_id,
|
113
|
+
service_prefix: service_prefix,
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# Add a rescue handler for a specific error. This allows libraries such as airbrake to hook into the error handling
|
119
|
+
# flow. When a rescue handler raises, it will look for a rescue handler for the parent class of the thrown error
|
120
|
+
# recursively until it reaches StandardError. If the block does not itself raise an error, the error may be
|
121
|
+
# swallowed.
|
122
|
+
#
|
123
|
+
# @param err [Class] the error class to handle
|
124
|
+
# @param block [Proc] the block to execute when the error is captured
|
125
|
+
def rescue_from(err, &block)
|
126
|
+
raise ArgumentError, "block required" unless block_given?
|
127
|
+
raise ArgumentError, "error must be a standard error" unless err.ancestors.include?(StandardError)
|
128
|
+
|
129
|
+
@rescue_handlers[err] = block
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# @private
|
134
|
+
def handle_error(error, parent = nil)
|
135
|
+
handler = select_rescue_handler_for(parent || error.class)
|
136
|
+
raise error unless handler
|
137
|
+
|
138
|
+
begin
|
139
|
+
handler.call(error)
|
140
|
+
rescue StandardError => e
|
141
|
+
# if the error was re-raised, and a new err was not raised then call the handler for the parent of the original
|
142
|
+
# error, otherwise, restart the chain
|
143
|
+
return handle_error(error, parent&.superclass || error.class.superclass) if error == e
|
144
|
+
|
145
|
+
handle_error(error)
|
146
|
+
end
|
95
147
|
end
|
96
148
|
|
97
149
|
private
|
98
150
|
|
151
|
+
def select_rescue_handler_for(error_class)
|
152
|
+
@rescue_handlers[error_class] || error_class.ancestors.map { |a| @rescue_handlers[a] }.compact.first
|
153
|
+
end
|
154
|
+
|
99
155
|
def accessors
|
100
156
|
self.class.accessors
|
101
157
|
end
|
data/lib/moleculer/node.rb
CHANGED
@@ -28,7 +28,7 @@ module Moleculer
|
|
28
28
|
svcs = options.fetch(:services)
|
29
29
|
# TODO: move this up to from_remote_info
|
30
30
|
svcs.map! { |service| Service.from_remote_info(service, self) } if svcs.first.is_a? Hash
|
31
|
-
@services = Hash[svcs.map { |s| [s.
|
31
|
+
@services = Hash[svcs.map { |s| [s.full_name, s] }]
|
32
32
|
end
|
33
33
|
|
34
34
|
def register_service(service)
|
@@ -81,14 +81,14 @@ module Moleculer
|
|
81
81
|
@local
|
82
82
|
end
|
83
83
|
|
84
|
-
def
|
84
|
+
def to_h
|
85
85
|
{
|
86
86
|
sender: @id,
|
87
87
|
config: {},
|
88
88
|
seq: 1,
|
89
89
|
ipList: [],
|
90
90
|
hostname: @hostname,
|
91
|
-
services: @services.values.map(&:
|
91
|
+
services: @services.values.map(&:to_h),
|
92
92
|
client: client_attrubutes,
|
93
93
|
}
|
94
94
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../support"
|
2
4
|
|
3
5
|
module Moleculer
|
@@ -6,25 +8,55 @@ module Moleculer
|
|
6
8
|
# @abstract Subclass for packet types.
|
7
9
|
class Base
|
8
10
|
include Support
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# this ensures that the packets get the accessors from the parent
|
14
|
+
def inherited(other)
|
15
|
+
other.instance_variable_set(:@packet_accessors, other.packet_accessors.merge(packet_accessors))
|
16
|
+
end
|
17
|
+
|
18
|
+
def packet_accessors
|
19
|
+
@packet_accessors ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Sets an accessor that fetches @data attributes
|
24
|
+
def packet_attr(name, default = :__not_defined__)
|
25
|
+
class_eval <<-ATTR, __FILE__, __LINE__ + 1
|
26
|
+
def #{name}
|
27
|
+
default = self.class.packet_accessors[:#{name}]
|
28
|
+
if default != :__not_defined__
|
29
|
+
return HashUtil.fetch(@data, :#{name}, default) unless default.is_a? Proc
|
30
|
+
return HashUtil.fetch(@data, :#{name}, default.call(self))
|
31
|
+
end
|
32
|
+
return HashUtil.fetch(@data, :#{name})
|
33
|
+
end
|
34
|
+
ATTR
|
35
|
+
packet_accessors[name] = default
|
36
|
+
end
|
37
|
+
|
38
|
+
def packet_name
|
39
|
+
name.split("::").last.upcase
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
9
43
|
##
|
10
44
|
# The protocol version
|
11
|
-
|
45
|
+
packet_attr :ver, "3"
|
12
46
|
|
13
47
|
##
|
14
48
|
# The sender of the packet
|
15
|
-
|
49
|
+
packet_attr :sender, ->(packet) { packet.config.node_id }
|
16
50
|
|
17
|
-
|
18
|
-
name.split("::").last.upcase
|
19
|
-
end
|
51
|
+
attr_reader :config
|
20
52
|
|
21
53
|
##
|
22
54
|
# @param data [Hash] the raw packet data
|
23
55
|
# @options data [String] :ver the protocol version, defaults to `'3'`
|
24
56
|
# @options data [String] :sender the packet sender, defaults to `Moleculer#node_id`
|
25
|
-
def initialize(data = {})
|
26
|
-
@
|
27
|
-
@
|
57
|
+
def initialize(config, data = {})
|
58
|
+
@data = data
|
59
|
+
@config = config
|
28
60
|
end
|
29
61
|
|
30
62
|
##
|
@@ -36,7 +68,7 @@ module Moleculer
|
|
36
68
|
"MOL.#{self.class.packet_name}"
|
37
69
|
end
|
38
70
|
|
39
|
-
def
|
71
|
+
def to_h
|
40
72
|
{
|
41
73
|
ver: ver,
|
42
74
|
sender: sender,
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "base"
|
2
4
|
|
3
5
|
module Moleculer
|
@@ -10,8 +12,8 @@ module Moleculer
|
|
10
12
|
:broadcast,
|
11
13
|
:groups
|
12
14
|
|
13
|
-
def initialize(data)
|
14
|
-
super(data)
|
15
|
+
def initialize(config, data = {})
|
16
|
+
super(config, data)
|
15
17
|
|
16
18
|
@event = HashUtil.fetch(data, :event)
|
17
19
|
@data = HashUtil.fetch(data, :data)
|
@@ -20,7 +22,7 @@ module Moleculer
|
|
20
22
|
@node = HashUtil.fetch(data, :node, nil)
|
21
23
|
end
|
22
24
|
|
23
|
-
def
|
25
|
+
def to_h
|
24
26
|
super.merge(
|
25
27
|
event: @event,
|
26
28
|
data: @data,
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "base"
|
2
4
|
|
3
5
|
module Moleculer
|
@@ -5,14 +7,11 @@ module Moleculer
|
|
5
7
|
##
|
6
8
|
# Represents a DISCOVER packet
|
7
9
|
class Heartbeat < Base
|
8
|
-
|
9
|
-
|
10
|
-
super(data)
|
10
|
+
def initialize(config, data = {})
|
11
|
+
super(config, data)
|
11
12
|
|
12
13
|
@cpu = 0
|
13
14
|
end
|
14
|
-
|
15
|
-
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -24,14 +24,14 @@ module Moleculer
|
|
24
24
|
:lang_version
|
25
25
|
|
26
26
|
def initialize(data)
|
27
|
-
@type = HashUtil.fetch(data, :type)
|
28
|
-
@version = HashUtil.fetch(data, :version)
|
29
|
-
@lang_version = HashUtil.fetch(data, :lang_version)
|
27
|
+
@type = HashUtil.fetch(data, :type, nil)
|
28
|
+
@version = HashUtil.fetch(data, :version, nil)
|
29
|
+
@lang_version = HashUtil.fetch(data, :lang_version, nil)
|
30
30
|
end
|
31
31
|
|
32
32
|
##
|
33
33
|
# @return [Hash] the object prepared for conversion to JSON for transmission
|
34
|
-
def
|
34
|
+
def to_h
|
35
35
|
{
|
36
36
|
type: @type,
|
37
37
|
version: @version,
|
@@ -64,34 +64,37 @@ module Moleculer
|
|
64
64
|
# @options data [Array<String>] ip_list the list of ip addresses for the node
|
65
65
|
# @options data [String] hostname the hostname of the node
|
66
66
|
# @options data [Hash] client the client data for the node
|
67
|
-
def initialize(data)
|
68
|
-
super(data)
|
67
|
+
def initialize(config, data = {})
|
68
|
+
super(config, data)
|
69
69
|
@services = HashUtil.fetch(data, :services)
|
70
|
-
@config = OpenStruct.new(Hash[HashUtil.fetch(data, :config).map { |i| [StringUtil.underscore(i[0]), i[1]] }])
|
71
70
|
@ip_list = HashUtil.fetch(data, :ip_list)
|
72
71
|
@hostname = HashUtil.fetch(data, :hostname)
|
73
|
-
@client = Client.new(HashUtil.fetch(data, :client))
|
74
|
-
|
72
|
+
@client = Client.new(HashUtil.fetch(data, :client, {}))
|
73
|
+
node = HashUtil.fetch(data, :node, nil)
|
74
|
+
@node_id = HashUtil.fetch(data, :node_id, node&.id)
|
75
75
|
end
|
76
76
|
|
77
77
|
def topic
|
78
|
-
if @
|
79
|
-
return "#{super}.#{@node.id}" if @node.is_a? Moleculer::Node
|
78
|
+
return "#{super}.#{@node_id}" if @node_id
|
80
79
|
|
81
|
-
return "#{super}.#{@node}"
|
82
|
-
end
|
83
80
|
super
|
84
81
|
end
|
85
82
|
|
86
|
-
def
|
83
|
+
def to_h
|
87
84
|
super.merge(
|
88
85
|
services: @services,
|
89
|
-
config:
|
86
|
+
config: config_for_hash,
|
90
87
|
ipList: @ip_list,
|
91
88
|
hostname: @hostname,
|
92
|
-
client: @client.
|
89
|
+
client: @client.to_h,
|
93
90
|
)
|
94
91
|
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def config_for_hash
|
96
|
+
Hash[config.to_h.reject { |a, _| a == :log_file }]
|
97
|
+
end
|
95
98
|
end
|
96
99
|
end
|
97
100
|
end
|
@@ -5,52 +5,35 @@ module Moleculer
|
|
5
5
|
##
|
6
6
|
# Represents a REQ packet
|
7
7
|
class Req < Base
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
:node
|
8
|
+
packet_attr :action
|
9
|
+
packet_attr :params
|
10
|
+
packet_attr :meta
|
11
|
+
packet_attr :timeout, nil
|
12
|
+
packet_attr :level, 1
|
13
|
+
packet_attr :parent_id, nil
|
14
|
+
packet_attr :request_id, nil
|
15
|
+
packet_attr :stream, false
|
16
|
+
packet_attr :metrics, false
|
17
|
+
packet_attr :id
|
18
|
+
packet_attr :node, nil
|
20
19
|
|
21
|
-
def
|
22
|
-
super(data)
|
23
|
-
|
24
|
-
@id = HashUtil.fetch(data, :id)
|
25
|
-
@action = HashUtil.fetch(data, :action)
|
26
|
-
@params = HashUtil.fetch(data, :params)
|
27
|
-
@meta = HashUtil.fetch(data, :meta)
|
28
|
-
@timeout = HashUtil.fetch(data, :timeout, nil)
|
29
|
-
@level = HashUtil.fetch(data, :level, 1)
|
30
|
-
@metrics = HashUtil.fetch(data, :metrics, false)
|
31
|
-
@parent_id = HashUtil.fetch(data, :parent_id, nil)
|
32
|
-
@request_id = HashUtil.fetch(data, :request_id, nil)
|
33
|
-
@stream = false
|
34
|
-
@node = HashUtil.fetch(data, :node, nil)
|
35
|
-
end
|
36
|
-
|
37
|
-
def as_json # rubocop:disable Metrics/MethodLength
|
20
|
+
def to_h # rubocop:disable Metrics/MethodLength
|
38
21
|
super.merge(
|
39
|
-
id:
|
40
|
-
action:
|
41
|
-
params:
|
42
|
-
meta:
|
43
|
-
timeout:
|
44
|
-
level:
|
45
|
-
metrics:
|
46
|
-
parent_id:
|
47
|
-
request_id:
|
48
|
-
stream:
|
22
|
+
id: id,
|
23
|
+
action: action,
|
24
|
+
params: params,
|
25
|
+
meta: meta,
|
26
|
+
timeout: timeout,
|
27
|
+
level: level,
|
28
|
+
metrics: metrics,
|
29
|
+
parent_id: parent_id,
|
30
|
+
request_id: request_id,
|
31
|
+
stream: stream,
|
49
32
|
)
|
50
33
|
end
|
51
34
|
|
52
35
|
def topic
|
53
|
-
"#{super}.#{
|
36
|
+
"#{super}.#{node.id}"
|
54
37
|
end
|
55
38
|
end
|
56
39
|
end
|
@@ -12,8 +12,8 @@ module Moleculer
|
|
12
12
|
:meta,
|
13
13
|
:stream
|
14
14
|
|
15
|
-
def initialize(data)
|
16
|
-
super(data)
|
15
|
+
def initialize(config, data)
|
16
|
+
super(config, data)
|
17
17
|
|
18
18
|
@id = HashUtil.fetch(data, :id)
|
19
19
|
@success = HashUtil.fetch(data, :success)
|
@@ -28,7 +28,7 @@ module Moleculer
|
|
28
28
|
"#{super}.#{@node.id}"
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
31
|
+
def to_h
|
32
32
|
super.merge(
|
33
33
|
id: @id,
|
34
34
|
success: @success,
|
data/lib/moleculer/registry.rb
CHANGED
@@ -42,11 +42,17 @@ module Moleculer
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def active_nodes
|
45
|
-
@nodes.values.select { |node| (Time.now - node[:node].last_heartbeat_at) <
|
45
|
+
@nodes.values.select { |node| (Time.now - node[:node].last_heartbeat_at) < expiration_interval }
|
46
46
|
end
|
47
47
|
|
48
48
|
def expired_nodes
|
49
|
-
@nodes.values.select { |node| (Time.now - node[:node].last_heartbeat_at) >
|
49
|
+
@nodes.values.select { |node| (Time.now - node[:node].last_heartbeat_at) > expiration_interval }
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def expiration_interval
|
55
|
+
@heartbeat_interval * 3
|
50
56
|
end
|
51
57
|
end
|
52
58
|
|
@@ -89,8 +95,8 @@ module Moleculer
|
|
89
95
|
end
|
90
96
|
|
91
97
|
def add_service(service)
|
92
|
-
@services[service.
|
93
|
-
@services[service.
|
98
|
+
@services[service.full_name] ||= NodeList.new(@heartbeat_interval)
|
99
|
+
@services[service.full_name].add_node(service.node)
|
94
100
|
end
|
95
101
|
|
96
102
|
def fetch_nodes
|
@@ -130,7 +136,7 @@ module Moleculer
|
|
130
136
|
def fetch_events(event_name)
|
131
137
|
return [] unless @events[event_name]
|
132
138
|
|
133
|
-
@events[event_name].fetch_nodes.map { |n| n.events[event_name] }.flatten.uniq { |e| e.service.
|
139
|
+
@events[event_name].fetch_nodes.map { |n| n.events[event_name] }.flatten.uniq { |e| e.service.full_name }
|
134
140
|
end
|
135
141
|
end
|
136
142
|
|
@@ -317,8 +323,8 @@ module Moleculer
|
|
317
323
|
|
318
324
|
def update_services(node)
|
319
325
|
node.services.values.each do |service|
|
320
|
-
@services[service.
|
321
|
-
@services[service.
|
326
|
+
@services[service.full_name] ||= NodeList.new(@heartbeat_interval)
|
327
|
+
@services[service.full_name].add_node(node)
|
322
328
|
end
|
323
329
|
end
|
324
330
|
end
|
@@ -7,16 +7,17 @@ module Moleculer
|
|
7
7
|
class Json
|
8
8
|
def initialize(config)
|
9
9
|
@logger = config.logger.get_child("[SERIALIZER]")
|
10
|
+
@config = config
|
10
11
|
end
|
11
12
|
|
12
13
|
def serialize(message)
|
13
|
-
message.
|
14
|
+
message.to_h.to_json
|
14
15
|
end
|
15
16
|
|
16
17
|
def deserialize(message)
|
17
18
|
JSON.parse(message)
|
18
19
|
rescue StandardError => e
|
19
|
-
@
|
20
|
+
@config.handle_error(e)
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
@@ -24,7 +24,6 @@ module Moleculer
|
|
24
24
|
@name = name
|
25
25
|
@service = service
|
26
26
|
@method = method
|
27
|
-
@service = service
|
28
27
|
@options = options
|
29
28
|
end
|
30
29
|
|
@@ -40,18 +39,16 @@ module Moleculer
|
|
40
39
|
|
41
40
|
response
|
42
41
|
rescue StandardError => e
|
43
|
-
|
44
|
-
|
45
|
-
broker.rescue_action.call(e)
|
42
|
+
broker.config.handle_error(e)
|
46
43
|
end
|
47
44
|
|
48
45
|
def node
|
49
46
|
@service.node
|
50
47
|
end
|
51
48
|
|
52
|
-
def
|
49
|
+
def to_h
|
53
50
|
{
|
54
|
-
name: "#{@service.
|
51
|
+
name: "#{@service.full_name}.#{name}",
|
55
52
|
rawName: name,
|
56
53
|
cache: HashUtil.fetch(@options, :cache, false),
|
57
54
|
metrics: {
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "action"
|
2
4
|
require_relative "event"
|
3
5
|
|
@@ -66,6 +68,15 @@ module Moleculer
|
|
66
68
|
events[name] = Event.new(name, self, method, options)
|
67
69
|
end
|
68
70
|
|
71
|
+
##
|
72
|
+
# Defines a version name or number on the service.
|
73
|
+
#
|
74
|
+
# @param ver [String|Number] the version of the service.
|
75
|
+
def version(ver = nil)
|
76
|
+
@version = ver if ver
|
77
|
+
@version
|
78
|
+
end
|
79
|
+
|
69
80
|
def actions
|
70
81
|
@actions ||= {}
|
71
82
|
end
|
@@ -74,8 +85,26 @@ module Moleculer
|
|
74
85
|
@events ||= {}
|
75
86
|
end
|
76
87
|
|
88
|
+
##
|
89
|
+
# @return [String] returns the full name of the service, including version and prefix
|
90
|
+
def full_name
|
91
|
+
return service_name unless @version
|
92
|
+
|
93
|
+
@full_name = service_name.dup
|
94
|
+
version = @version.to_s
|
95
|
+
version.prepend("v") if @version.is_a? Numeric
|
96
|
+
|
97
|
+
if @full_name.include?(".")
|
98
|
+
@full_name.sub!(".", ".#{version}.")
|
99
|
+
elsif version
|
100
|
+
@full_name.prepend("#{version}.")
|
101
|
+
end
|
102
|
+
|
103
|
+
@full_name
|
104
|
+
end
|
105
|
+
|
77
106
|
def action_name_for(name)
|
78
|
-
"#{
|
107
|
+
"#{full_name}.#{name}"
|
79
108
|
end
|
80
109
|
end
|
81
110
|
|
@@ -103,13 +132,14 @@ module Moleculer
|
|
103
132
|
self.class.broker
|
104
133
|
end
|
105
134
|
|
106
|
-
def self.
|
135
|
+
def self.to_h # rubocop:disable Metrics/AbcSize
|
107
136
|
{
|
108
|
-
name:
|
137
|
+
name: full_name,
|
138
|
+
version: version,
|
109
139
|
settings: {},
|
110
140
|
metadata: {},
|
111
|
-
actions: Hash[actions.values.map { |a| [a.name.to_sym, a.
|
112
|
-
events: Hash[events.values.map { |e| [e.name.to_sym, e.
|
141
|
+
actions: Hash[actions.values.map { |a| [a.name.to_sym, a.to_h] }],
|
142
|
+
events: Hash[events.values.map { |e| [e.name.to_sym, e.to_h] }],
|
113
143
|
}
|
114
144
|
end
|
115
145
|
end
|
@@ -32,9 +32,7 @@ module Moleculer
|
|
32
32
|
def execute(data, broker)
|
33
33
|
@service.new(broker).public_send(@method, data)
|
34
34
|
rescue StandardError => e
|
35
|
-
|
36
|
-
|
37
|
-
broker.rescue_event.call(e)
|
35
|
+
broker.config.handle_error(e)
|
38
36
|
end
|
39
37
|
|
40
38
|
##
|
@@ -45,7 +43,7 @@ module Moleculer
|
|
45
43
|
|
46
44
|
##
|
47
45
|
# @return [Hash] a hash representing this event as it would be in JSON
|
48
|
-
def
|
46
|
+
def to_h
|
49
47
|
{
|
50
48
|
name: name,
|
51
49
|
}
|
@@ -7,8 +7,8 @@ module Moleculer
|
|
7
7
|
class OpenStruct < ::OpenStruct
|
8
8
|
##
|
9
9
|
# @return [Hash] the object prepared for conversion to JSON for transmission
|
10
|
-
def
|
11
|
-
Hash[
|
10
|
+
def to_h
|
11
|
+
Hash[super.map { |item| [StringUtil.camelize(item[0]), item[1]] }]
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "base"
|
2
4
|
|
3
5
|
module Moleculer
|
@@ -11,14 +13,18 @@ module Moleculer
|
|
11
13
|
# in this case we want to use a class var as this needs to behave like a singleton to mimic how a global
|
12
14
|
# transporter functions
|
13
15
|
@@subscriptions ||= {} # rubocop:disable Style/ClassVars
|
16
|
+
@logger = config.logger.get_child("[FAKE.TRANSPORTER]")
|
14
17
|
end
|
15
18
|
|
16
19
|
def subscribe(channel, &block)
|
17
|
-
@@subscriptions[channel]
|
20
|
+
@@subscriptions[channel] ||= []
|
21
|
+
@@subscriptions[channel] << block
|
18
22
|
end
|
19
23
|
|
20
24
|
def publish(packet)
|
21
|
-
|
25
|
+
@logger.debug "publishing packet to '#{packet.topic}'", packet.to_h
|
26
|
+
@logger.debug "processing #{@@subscriptions[packet.topic].length} callbacks for '#{packet.topic}'"
|
27
|
+
@@subscriptions[packet.topic].each { |c| c.call(packet) }
|
22
28
|
end
|
23
29
|
|
24
30
|
def start
|
@@ -22,7 +22,7 @@ module Moleculer
|
|
22
22
|
# Publishes the packet to the packet's topic
|
23
23
|
def publish(packet)
|
24
24
|
topic = packet.topic
|
25
|
-
@logger.debug "publishing packet to '#{topic}'", packet.
|
25
|
+
@logger.debug "publishing packet to '#{topic}'", packet.to_h
|
26
26
|
connection.publish(topic, @serializer.serialize(packet))
|
27
27
|
end
|
28
28
|
|
@@ -61,6 +61,7 @@ module Moleculer
|
|
61
61
|
@logger = config.logger.get_child("[REDIS.TRANSPORTER.SUBSCRIPTION.#{channel}]")
|
62
62
|
@serializer = Serializers.for(config.serializer).new(config)
|
63
63
|
@node_id = config.node_id
|
64
|
+
@config = config
|
64
65
|
|
65
66
|
# it is necessary to send some sort of message to signal the subscriber to disconnect and shutdown
|
66
67
|
# this is an internal message
|
@@ -121,11 +122,11 @@ module Moleculer
|
|
121
122
|
def process_packet(packet)
|
122
123
|
return @connection.unsubscribe if packet == :disconnect
|
123
124
|
|
124
|
-
@logger.trace "received packet from #{packet.sender}:", packet.
|
125
|
+
@logger.trace "received packet from #{packet.sender}:", packet.to_h
|
125
126
|
|
126
127
|
@block.call(packet)
|
127
|
-
rescue StandardError =>
|
128
|
-
@
|
128
|
+
rescue StandardError => e
|
129
|
+
@config.handle_error(e)
|
129
130
|
end
|
130
131
|
|
131
132
|
def process_message(message)
|
@@ -140,9 +141,9 @@ module Moleculer
|
|
140
141
|
return nil unless parsed
|
141
142
|
|
142
143
|
|
143
|
-
packet_type.new(parsed)
|
144
|
-
rescue StandardError =>
|
145
|
-
@
|
144
|
+
packet_type.new(@config, parsed)
|
145
|
+
rescue StandardError => e
|
146
|
+
@config.handle_error(e)
|
146
147
|
end
|
147
148
|
|
148
149
|
def unsubscribe
|
data/lib/moleculer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moleculer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fugufish
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -249,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
249
249
|
- !ruby/object:Gem::Version
|
250
250
|
version: '0'
|
251
251
|
requirements: []
|
252
|
-
rubygems_version: 3.0.
|
252
|
+
rubygems_version: 3.0.4
|
253
253
|
signing_key:
|
254
254
|
specification_version: 4
|
255
255
|
summary: This is a Ruby implementation of the Moleculer framework.
|