rsmp 0.8.0 → 0.8.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 +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
|