rsmp 0.8.0 → 0.8.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 +4 -4
- data/Gemfile.lock +3 -3
- data/config/tlc.yaml +8 -6
- data/documentation/classes_and_modules.md +1 -4
- data/documentation/collecting_message.md +196 -0
- data/lib/rsmp/collect/aggregated_status_collector.rb +9 -0
- data/lib/rsmp/collect/collector.rb +92 -59
- data/lib/rsmp/collect/command_query.rb +16 -0
- data/lib/rsmp/collect/command_response_collector.rb +20 -0
- data/lib/rsmp/collect/filter.rb +31 -0
- data/lib/rsmp/collect/listener.rb +0 -8
- data/lib/rsmp/collect/message_matchers.rb +0 -64
- data/lib/rsmp/collect/query.rb +16 -6
- data/lib/rsmp/collect/{matcher.rb → state_collector.rb} +19 -9
- data/lib/rsmp/collect/status_collector.rb +20 -0
- data/lib/rsmp/collect/{message_queries.rb → status_query.rb} +0 -15
- data/lib/rsmp/node.rb +0 -1
- data/lib/rsmp/proxy.rb +15 -19
- data/lib/rsmp/site.rb +3 -2
- data/lib/rsmp/site_proxy.rb +34 -46
- data/lib/rsmp/supervisor_proxy.rb +3 -11
- data/lib/rsmp/tlc/signal_group.rb +15 -7
- data/lib/rsmp/tlc/traffic_controller.rb +92 -28
- data/lib/rsmp/tlc/traffic_controller_site.rb +10 -1
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp.rb +7 -3
- metadata +10 -5
- data/lib/rsmp/collect/message_collector.rb +0 -209
data/lib/rsmp.rb
CHANGED
@@ -20,10 +20,14 @@ require 'rsmp/components'
|
|
20
20
|
require 'rsmp/collect/notifier'
|
21
21
|
require 'rsmp/collect/listener'
|
22
22
|
require 'rsmp/collect/collector'
|
23
|
+
require 'rsmp/collect/state_collector'
|
24
|
+
require 'rsmp/collect/filter'
|
23
25
|
require 'rsmp/collect/query'
|
24
|
-
require 'rsmp/collect/
|
25
|
-
require 'rsmp/collect/
|
26
|
-
require 'rsmp/collect/
|
26
|
+
require 'rsmp/collect/status_query'
|
27
|
+
require 'rsmp/collect/command_query'
|
28
|
+
require 'rsmp/collect/status_collector'
|
29
|
+
require 'rsmp/collect/command_response_collector'
|
30
|
+
require 'rsmp/collect/aggregated_status_collector'
|
27
31
|
require 'rsmp/component'
|
28
32
|
require 'rsmp/site'
|
29
33
|
require 'rsmp/proxy'
|
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.8.
|
4
|
+
version: 0.8.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: 2022-01-
|
11
|
+
date: 2022-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -201,19 +201,24 @@ files:
|
|
201
201
|
- config/supervisor.yaml
|
202
202
|
- config/tlc.yaml
|
203
203
|
- documentation/classes_and_modules.md
|
204
|
+
- documentation/collecting_message.md
|
204
205
|
- documentation/message_distribution.md
|
205
206
|
- exe/rsmp
|
206
207
|
- lib/rsmp.rb
|
207
208
|
- lib/rsmp/archive.rb
|
208
209
|
- lib/rsmp/cli.rb
|
210
|
+
- lib/rsmp/collect/aggregated_status_collector.rb
|
209
211
|
- lib/rsmp/collect/collector.rb
|
212
|
+
- lib/rsmp/collect/command_query.rb
|
213
|
+
- lib/rsmp/collect/command_response_collector.rb
|
214
|
+
- lib/rsmp/collect/filter.rb
|
210
215
|
- lib/rsmp/collect/listener.rb
|
211
|
-
- lib/rsmp/collect/matcher.rb
|
212
|
-
- lib/rsmp/collect/message_collector.rb
|
213
216
|
- lib/rsmp/collect/message_matchers.rb
|
214
|
-
- lib/rsmp/collect/message_queries.rb
|
215
217
|
- lib/rsmp/collect/notifier.rb
|
216
218
|
- lib/rsmp/collect/query.rb
|
219
|
+
- lib/rsmp/collect/state_collector.rb
|
220
|
+
- lib/rsmp/collect/status_collector.rb
|
221
|
+
- lib/rsmp/collect/status_query.rb
|
217
222
|
- lib/rsmp/component.rb
|
218
223
|
- lib/rsmp/components.rb
|
219
224
|
- lib/rsmp/convert/export/json_schema.rb
|
@@ -1,209 +0,0 @@
|
|
1
|
-
module RSMP
|
2
|
-
|
3
|
-
# Collects ingoing and/or outgoing messages from a notifier.
|
4
|
-
# Can filter by message type and wakes up the client once the desired number of messages has been collected.
|
5
|
-
class MessageCollector < Collector
|
6
|
-
attr_reader :condition, :messages, :done
|
7
|
-
|
8
|
-
def initialize proxy, options={}
|
9
|
-
super proxy, options
|
10
|
-
@options = {
|
11
|
-
cancel: {
|
12
|
-
schema_error: true,
|
13
|
-
disconnect: false,
|
14
|
-
}
|
15
|
-
}.deep_merge options
|
16
|
-
@ingoing = options[:ingoing] == nil ? true : options[:ingoing]
|
17
|
-
@outgoing = options[:outgoing] == nil ? false : options[:outgoing]
|
18
|
-
@condition = Async::Notification.new
|
19
|
-
@title = options[:title] || [@options[:type]].flatten.join('/')
|
20
|
-
@options[:timeout] ||= 1
|
21
|
-
@options[:num] ||= 1
|
22
|
-
reset
|
23
|
-
end
|
24
|
-
|
25
|
-
# Inspect formatter that shows the message we have collected
|
26
|
-
def inspect
|
27
|
-
"#<#{self.class.name}:#{self.object_id}, #{inspector(:@messages)}>"
|
28
|
-
end
|
29
|
-
|
30
|
-
# Want ingoing messages?
|
31
|
-
def ingoing?
|
32
|
-
@ingoing == true
|
33
|
-
end
|
34
|
-
|
35
|
-
# Want outgoing messages?
|
36
|
-
def outgoing?
|
37
|
-
@outgoing == true
|
38
|
-
end
|
39
|
-
|
40
|
-
# Block until all messages have been collected
|
41
|
-
def wait
|
42
|
-
@condition.wait
|
43
|
-
end
|
44
|
-
|
45
|
-
# Collect message
|
46
|
-
# Will block until all messages have been collected,
|
47
|
-
# or we time out
|
48
|
-
def collect task, options={}, &block
|
49
|
-
@options.merge! options
|
50
|
-
@block = block
|
51
|
-
unless @done
|
52
|
-
listen do
|
53
|
-
task.with_timeout(@options[:timeout]) do
|
54
|
-
@condition.wait
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
return @error if @error
|
59
|
-
self
|
60
|
-
rescue Async::TimeoutError
|
61
|
-
str = "#{@title.capitalize} collection"
|
62
|
-
str << " in response to #{options[:m_id]}" if options[:m_id]
|
63
|
-
str << " didn't complete within #{@options[:timeout]}s"
|
64
|
-
reached = progress
|
65
|
-
str << ", reached #{progress[:reached]}/#{progress[:need]}"
|
66
|
-
raise RSMP::TimeoutError.new str
|
67
|
-
end
|
68
|
-
|
69
|
-
# Return progress as collected vs. number requested
|
70
|
-
def progress
|
71
|
-
need = @options[:num]
|
72
|
-
reached = @messages.size
|
73
|
-
{ need: need, got: reached }
|
74
|
-
end
|
75
|
-
|
76
|
-
# Get the collected message.
|
77
|
-
def message
|
78
|
-
@messages.first
|
79
|
-
end
|
80
|
-
|
81
|
-
# Get the collected messages.
|
82
|
-
def messages
|
83
|
-
@messages
|
84
|
-
end
|
85
|
-
|
86
|
-
# Clear all query results
|
87
|
-
def reset
|
88
|
-
@messages = []
|
89
|
-
@error = nil
|
90
|
-
@done = false
|
91
|
-
end
|
92
|
-
|
93
|
-
# Check if we receive a NotAck related to initiating request, identified by @m_id.
|
94
|
-
def check_not_ack message
|
95
|
-
return unless @options[:m_id]
|
96
|
-
if message.is_a?(MessageNotAck)
|
97
|
-
if message.attribute('oMId') == @options[:m_id]
|
98
|
-
m_id_short = RSMP::Message.shorten_m_id @options[:m_id], 8
|
99
|
-
@error = RSMP::MessageRejected.new("#{@title} #{m_id_short} was rejected with '#{message.attribute('rea')}'")
|
100
|
-
complete
|
101
|
-
end
|
102
|
-
false
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# Handle message. and return true when we're done collecting
|
107
|
-
def notify message
|
108
|
-
raise ArgumentError unless message
|
109
|
-
raise RuntimeError.new("can't process message when already done") if @done
|
110
|
-
check_not_ack(message)
|
111
|
-
return true if @done
|
112
|
-
perform_match message
|
113
|
-
complete if done?
|
114
|
-
@done
|
115
|
-
end
|
116
|
-
|
117
|
-
# Match message against our collection criteria
|
118
|
-
def perform_match message
|
119
|
-
matched = type_match?(message) && block_match?(message)
|
120
|
-
if matched == true
|
121
|
-
keep message
|
122
|
-
elsif matched == false
|
123
|
-
forget message
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Have we collected the required number of messages?
|
128
|
-
def done?
|
129
|
-
@options[:num] && @messages.size >= @options[:num]
|
130
|
-
end
|
131
|
-
|
132
|
-
# Called when we're done collecting. Remove ourself as a listener,
|
133
|
-
# se we don't receive message notifications anymore
|
134
|
-
def complete
|
135
|
-
@done = true
|
136
|
-
@proxy.remove_listener self
|
137
|
-
@condition.signal
|
138
|
-
end
|
139
|
-
|
140
|
-
# The proxy experienced some error.
|
141
|
-
# Check if this should cause us to cancel.
|
142
|
-
def notify_error error, options={}
|
143
|
-
case error
|
144
|
-
when RSMP::SchemaError
|
145
|
-
notify_schema_error error, options
|
146
|
-
when RSMP::ConnectionError
|
147
|
-
notify_disconnect error, options
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
# Cancel if we received e schema error for a message type we're collecting
|
152
|
-
def notify_schema_error error, options
|
153
|
-
return unless @options.dig(:cancel,:schema_error)
|
154
|
-
message = options[:message]
|
155
|
-
return unless message
|
156
|
-
klass = message.class.name.split('::').last
|
157
|
-
return unless [@options[:type]].flatten.include? klass
|
158
|
-
@proxy.log "Collect cancelled due to schema error in #{klass} #{message.m_id_short}", level: :debug
|
159
|
-
cancel error
|
160
|
-
end
|
161
|
-
|
162
|
-
# Cancel if we received e notificaiton about a disconnect
|
163
|
-
def notify_disconnect error, options
|
164
|
-
return unless @options.dig(:cancel,:disconnect)
|
165
|
-
@proxy.log "Collect cancelled due to a connection error: #{error.to_s}", level: :debug
|
166
|
-
cancel error
|
167
|
-
end
|
168
|
-
|
169
|
-
# Abort collection
|
170
|
-
def cancel error
|
171
|
-
@error = error if error
|
172
|
-
@done = false
|
173
|
-
@proxy.remove_listener self
|
174
|
-
@condition.signal
|
175
|
-
end
|
176
|
-
|
177
|
-
# Store a message in the result array
|
178
|
-
def keep message
|
179
|
-
@messages << message
|
180
|
-
end
|
181
|
-
|
182
|
-
# Remove a message from the result array
|
183
|
-
def forget message
|
184
|
-
@messages.delete message
|
185
|
-
end
|
186
|
-
|
187
|
-
# Check a message against our match criteria
|
188
|
-
# Return true if there's a match, false if not
|
189
|
-
def type_match? message
|
190
|
-
return false if message.direction == :in && @ingoing == false
|
191
|
-
return false if message.direction == :out && @outgoing == false
|
192
|
-
if @options[:type]
|
193
|
-
if @options[:type].is_a? Array
|
194
|
-
return false unless @options[:type].include? message.type
|
195
|
-
else
|
196
|
-
return false unless message.type == @options[:type]
|
197
|
-
end
|
198
|
-
end
|
199
|
-
if @options[:component]
|
200
|
-
return false if message.attributes['cId'] && message.attributes['cId'] != @options[:component]
|
201
|
-
end
|
202
|
-
true
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
def block_match? message
|
207
|
-
@block.call(message) == true
|
208
|
-
end
|
209
|
-
end
|