rsmp 0.3.0 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/rsmp/collector.rb +15 -6
- data/lib/rsmp/components.rb +10 -0
- data/lib/rsmp/matcher.rb +27 -15
- data/lib/rsmp/proxy.rb +14 -3
- data/lib/rsmp/site.rb +8 -2
- data/lib/rsmp/site_proxy.rb +3 -3
- data/lib/rsmp/supervisor.rb +1 -1
- data/lib/rsmp/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: f529bfbfcdd5fc6b0854c294e2412c5e7da10e2595a6a20ab0f6c65b7eb28964
|
4
|
+
data.tar.gz: c8fb86566e623a27ec78784e3d0299f16d082edc87ad9438f2335a0c33657b39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58c5d44cb5d8a1f87b77d91823eaa76adfd437df955412ba42950e359d1b08b47acec78034f42524b72d474a6c7870e2e22f418973d634fc938650b13f95fc47
|
7
|
+
data.tar.gz: 6006f41562af7ce3419c50895040fc0682026fa3c5b0db113875645fdd1de5286e25b73edc22f1d547a1daac50059532e7c4061cc5e3789d3a92c18c5e502aca
|
data/Gemfile.lock
CHANGED
data/lib/rsmp/collector.rb
CHANGED
@@ -13,6 +13,7 @@ module RSMP
|
|
13
13
|
@condition = Async::Notification.new
|
14
14
|
@title = options[:title] || [@options[:type]].flatten.join('/')
|
15
15
|
@options[:timeout] ||= 1
|
16
|
+
@options[:num] ||= 1
|
16
17
|
reset
|
17
18
|
end
|
18
19
|
|
@@ -51,21 +52,21 @@ module RSMP
|
|
51
52
|
raise RSMP::TimeoutError.new str
|
52
53
|
end
|
53
54
|
|
55
|
+
# Get the collected messages.
|
56
|
+
# If one message was requested, return it as a plain object instead of array
|
54
57
|
def result
|
55
|
-
return @messages.first if @options[:num] == 1
|
56
|
-
@messages.first @options[:num]
|
58
|
+
return @messages.first if @options[:num] == 1
|
59
|
+
@messages.first @options[:num]
|
57
60
|
end
|
58
61
|
|
62
|
+
# Clear all query results
|
59
63
|
def reset
|
60
64
|
@messages = []
|
61
65
|
@error = nil
|
62
66
|
@done = false
|
63
67
|
end
|
64
68
|
|
65
|
-
# Check
|
66
|
-
# If the original request identified by @m_id is rejected, set the result to an exception,
|
67
|
-
# which will be returned by the async task and stored as the task result.
|
68
|
-
# When the parent task call wait() on the task, the exception will be raised in the parent task.
|
69
|
+
# Check if we receive a NotAck related to initiating request, identified by @m_id.
|
69
70
|
def check_not_ack message
|
70
71
|
return unless @options[:m_id]
|
71
72
|
if message.is_a?(MessageNotAck)
|
@@ -81,6 +82,7 @@ module RSMP
|
|
81
82
|
# Handle message. and return true when we're done collecting
|
82
83
|
def notify message
|
83
84
|
raise ArgumentError unless message
|
85
|
+
raise RuntimeError.new("can't process message when already done") if @done
|
84
86
|
check_not_ack(message)
|
85
87
|
return true if @done
|
86
88
|
check_match message
|
@@ -98,24 +100,31 @@ module RSMP
|
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
103
|
+
# Have we collected the required number of messages?
|
101
104
|
def done?
|
102
105
|
@options[:num] && @messages.size >= @options[:num]
|
103
106
|
end
|
104
107
|
|
108
|
+
# Called when we're done collecting. Remove ourself as a listener,
|
109
|
+
# se we don't receive message notifications anymore
|
105
110
|
def complete
|
106
111
|
@done = true
|
107
112
|
@proxy.remove_listener self
|
108
113
|
@condition.signal
|
109
114
|
end
|
110
115
|
|
116
|
+
# Store a message in the result array
|
111
117
|
def keep message
|
112
118
|
@messages << message
|
113
119
|
end
|
114
120
|
|
121
|
+
# Remove a message from the result array
|
115
122
|
def forget message
|
116
123
|
@messages.delete message
|
117
124
|
end
|
118
125
|
|
126
|
+
# Check a message against our match criteria
|
127
|
+
# Return true if there's a match
|
119
128
|
def match? message
|
120
129
|
raise ArgumentError unless message
|
121
130
|
return if message.direction == :in && @ingoing == false
|
data/lib/rsmp/components.rb
CHANGED
@@ -13,6 +13,7 @@ module RSMP
|
|
13
13
|
|
14
14
|
def setup_components settings
|
15
15
|
return unless settings
|
16
|
+
check_main_component settings
|
16
17
|
settings.each_pair do |type,components_by_type|
|
17
18
|
components_by_type.each_pair do |id,settings|
|
18
19
|
@components[id] = build_component(id:id, type:type, settings:settings)
|
@@ -20,6 +21,15 @@ module RSMP
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
24
|
+
def check_main_component settings
|
25
|
+
unless settings['main'] && settings['main'].size >= 1
|
26
|
+
raise ConfigurationError.new("main component must be defined")
|
27
|
+
end
|
28
|
+
if settings['main'].size > 1
|
29
|
+
raise ConfigurationError.new("only one main component can be defined, found #{settings['main'].keys.join(', ')}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
23
33
|
def add_component component
|
24
34
|
@components[component.c_id] = component
|
25
35
|
end
|
data/lib/rsmp/matcher.rb
CHANGED
@@ -35,6 +35,7 @@ module RSMP
|
|
35
35
|
#
|
36
36
|
#
|
37
37
|
class Matcher < Collector
|
38
|
+
attr_reader :queries
|
38
39
|
|
39
40
|
# Initialize with a list a wanted statuses
|
40
41
|
def initialize proxy, want, options={}
|
@@ -55,16 +56,27 @@ module RSMP
|
|
55
56
|
@queries.map { |query,result| result[:message] }.uniq
|
56
57
|
end
|
57
58
|
|
58
|
-
#
|
59
|
+
# Get items from results
|
59
60
|
def items
|
60
61
|
@queries.map { |query,result| result[:item] }.uniq
|
61
62
|
end
|
62
63
|
|
63
|
-
#
|
64
|
+
# Are there queries left to match?
|
64
65
|
def done?
|
65
66
|
@queries.values.all? { |result| result != nil }
|
66
67
|
end
|
67
68
|
|
69
|
+
# Get a simplified hash of queries, with values set to either true or false,
|
70
|
+
# indicating which queries have been matched.
|
71
|
+
def status
|
72
|
+
@queries.transform_values{ |v| v != nil }
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get a simply array of bools, showing which queries ahve been matched.
|
76
|
+
def summary
|
77
|
+
@queries.values.map { |v| v != nil }
|
78
|
+
end
|
79
|
+
|
68
80
|
# Mark a query as matched, by linking it to the matched item and message
|
69
81
|
def keep query, message, item
|
70
82
|
@queries[query] = { message:message, item:item }
|
@@ -75,11 +87,12 @@ module RSMP
|
|
75
87
|
@queries[query] = nil
|
76
88
|
end
|
77
89
|
|
78
|
-
# Check if a messages
|
79
|
-
#
|
90
|
+
# Check if a messages matches our criteria.
|
91
|
+
# We iterate through each of the status items or return values in the message
|
92
|
+
# Breaks as soon as where done matching all queries
|
80
93
|
def check_match message
|
81
94
|
return unless match?(message)
|
82
|
-
@queries.keys.each do |query|
|
95
|
+
@queries.keys.each do |query| # look through queries
|
83
96
|
get_items(message).each do |item| # look through status items in message
|
84
97
|
break if check_item_match message, query, item
|
85
98
|
end
|
@@ -104,15 +117,16 @@ module RSMP
|
|
104
117
|
def initialize proxy, want, options={}
|
105
118
|
super proxy, want, options.merge(
|
106
119
|
type: ['CommandResponse','MessageNotAck'],
|
107
|
-
title:'command
|
120
|
+
title:'command response'
|
108
121
|
)
|
109
122
|
end
|
110
123
|
|
124
|
+
# Get items, in our case the return values
|
111
125
|
def get_items message
|
112
126
|
message.attributes['rvs']
|
113
127
|
end
|
114
128
|
|
115
|
-
# Match
|
129
|
+
# Match a return value item against a query
|
116
130
|
def match_item? query, item
|
117
131
|
return nil if query['cCI'] && query['cCI'] != item['cCI']
|
118
132
|
return nil if query['n'] && query['n'] != item['n']
|
@@ -131,11 +145,12 @@ module RSMP
|
|
131
145
|
super proxy, want, options.merge
|
132
146
|
end
|
133
147
|
|
148
|
+
# Get items, in our case status values
|
134
149
|
def get_items message
|
135
150
|
message.attributes['sS']
|
136
151
|
end
|
137
152
|
|
138
|
-
# Match
|
153
|
+
# Match a status value against a query
|
139
154
|
def match_item? query, item
|
140
155
|
return nil if query['sCI'] && query['sCI'] != item['sCI']
|
141
156
|
return nil if query['cO'] && query['cO'] != item['cO']
|
@@ -155,7 +170,7 @@ module RSMP
|
|
155
170
|
def initialize proxy, want, options={}
|
156
171
|
super proxy, want, options.merge(
|
157
172
|
type: ['StatusResponse','MessageNotAck'],
|
158
|
-
title: 'status
|
173
|
+
title: 'status response'
|
159
174
|
)
|
160
175
|
end
|
161
176
|
end
|
@@ -165,7 +180,7 @@ module RSMP
|
|
165
180
|
def initialize proxy, want, options={}
|
166
181
|
super proxy, want, options.merge(
|
167
182
|
type: ['StatusUpdate','MessageNotAck'],
|
168
|
-
title:'status
|
183
|
+
title:'status update'
|
169
184
|
)
|
170
185
|
end
|
171
186
|
end
|
@@ -173,11 +188,8 @@ module RSMP
|
|
173
188
|
# Class for waiting for an aggregated status response
|
174
189
|
class AggregatedStatusMatcher < Collector
|
175
190
|
def initialize proxy, options={}
|
176
|
-
|
177
|
-
|
178
|
-
type: ['AggregatedStatus','MessageNotAck'],
|
179
|
-
title: 'aggregated status request'
|
180
|
-
)
|
191
|
+
required = { type: ['AggregatedStatus','MessageNotAck'], title: 'aggregated status' }
|
192
|
+
super proxy, options.merge(required)
|
181
193
|
end
|
182
194
|
end
|
183
195
|
end
|
data/lib/rsmp/proxy.rb
CHANGED
@@ -124,7 +124,11 @@ module RSMP
|
|
124
124
|
message = process_packet json
|
125
125
|
duration = Time.now - beginning
|
126
126
|
ms = (duration*1000).round(4)
|
127
|
-
|
127
|
+
if duration > 0
|
128
|
+
per_second = (1.0 / duration).round
|
129
|
+
else
|
130
|
+
per_second = Float::INFINITY
|
131
|
+
end
|
128
132
|
if message
|
129
133
|
type = message.type
|
130
134
|
m_id = Logger.shorten_message_id(message.m_id)
|
@@ -203,7 +207,6 @@ module RSMP
|
|
203
207
|
def watchdog_send_timer now
|
204
208
|
return unless @watchdog_started
|
205
209
|
return if @site_settings['intervals']['watchdog'] == :never
|
206
|
-
|
207
210
|
if @latest_watchdog_send_at == nil
|
208
211
|
send_watchdog now
|
209
212
|
else
|
@@ -299,10 +302,18 @@ module RSMP
|
|
299
302
|
end
|
300
303
|
end
|
301
304
|
|
305
|
+
def should_validate_ingoing_message? message
|
306
|
+
return false unless @site_settings
|
307
|
+
skip = @site_settings.dig('skip_validation')
|
308
|
+
return false unless skip
|
309
|
+
klass = message.class.name.split('::').last
|
310
|
+
!skip.include?(klass)
|
311
|
+
end
|
312
|
+
|
302
313
|
def process_packet json
|
303
314
|
attributes = Message.parse_attributes json
|
304
315
|
message = Message.build attributes, json
|
305
|
-
message.validate
|
316
|
+
message.validate(get_schemas) if should_validate_ingoing_message?(message)
|
306
317
|
notify message
|
307
318
|
expect_version_message(message) unless @version_determined
|
308
319
|
process_message message
|
data/lib/rsmp/site.rb
CHANGED
@@ -41,10 +41,16 @@ module RSMP
|
|
41
41
|
},
|
42
42
|
'send_after_connect' => true,
|
43
43
|
'components' => {
|
44
|
-
'
|
44
|
+
'main' => {
|
45
|
+
'C1' => {}
|
46
|
+
}
|
45
47
|
}
|
46
48
|
}
|
47
|
-
|
49
|
+
# only one main component can be defined, so replace the default if options define one
|
50
|
+
if options.dig(:site_settings,'components','main')
|
51
|
+
defaults['components']['main'] = options[:site_settings]['components']['main']
|
52
|
+
end
|
53
|
+
|
48
54
|
@site_settings = defaults.deep_merge options[:site_settings]
|
49
55
|
check_sxl_version
|
50
56
|
setup_components @site_settings['components']
|
data/lib/rsmp/site_proxy.rb
CHANGED
@@ -11,7 +11,7 @@ module RSMP
|
|
11
11
|
initialize_components
|
12
12
|
@supervisor = options[:supervisor]
|
13
13
|
@settings = @supervisor.supervisor_settings.clone
|
14
|
-
@site_id =
|
14
|
+
@site_id = options[:site_id]
|
15
15
|
end
|
16
16
|
|
17
17
|
def revive options
|
@@ -103,7 +103,7 @@ module RSMP
|
|
103
103
|
})
|
104
104
|
if options[:collect]
|
105
105
|
task = @task.async do |task|
|
106
|
-
|
106
|
+
collect_aggregated_status task, options[:collect].merge(m_id: m_id)
|
107
107
|
end
|
108
108
|
send_message message, validate: options[:validate]
|
109
109
|
return message, task.wait
|
@@ -369,7 +369,7 @@ module RSMP
|
|
369
369
|
CommandResponseMatcher.new(self, command_list, options).collect task
|
370
370
|
end
|
371
371
|
|
372
|
-
def
|
372
|
+
def collect_aggregated_status task, options
|
373
373
|
AggregatedStatusMatcher.new(self, options).collect task
|
374
374
|
end
|
375
375
|
end
|
data/lib/rsmp/supervisor.rb
CHANGED
@@ -175,7 +175,7 @@ module RSMP
|
|
175
175
|
proxy.revive settings
|
176
176
|
else
|
177
177
|
check_max_sites
|
178
|
-
proxy = build_proxy settings
|
178
|
+
proxy = build_proxy settings.merge(site_id:id) # keep the id learned by peeking above
|
179
179
|
@proxies.push proxy
|
180
180
|
end
|
181
181
|
proxy.run # will run until the site disconnects
|
data/lib/rsmp/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsmp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emil Tin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -255,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
255
|
- !ruby/object:Gem::Version
|
256
256
|
version: '0'
|
257
257
|
requirements: []
|
258
|
-
rubygems_version: 3.2.
|
258
|
+
rubygems_version: 3.2.15
|
259
259
|
signing_key:
|
260
260
|
specification_version: 4
|
261
261
|
summary: RoadSide Message Protocol (RSMP) library.
|