rsmp 0.1.19 → 0.1.31
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/.gitmodules +0 -4
- data/Gemfile.lock +16 -14
- data/config/supervisor.yaml +9 -15
- data/config/tlc.yaml +9 -8
- data/documentation/{classes.md → classes_and_modules.md} +25 -22
- data/documentation/message_distribution.md +23 -0
- data/lib/rsmp.rb +14 -5
- data/lib/rsmp/archive.rb +12 -17
- data/lib/rsmp/cli.rb +133 -102
- data/lib/rsmp/collector.rb +102 -0
- data/lib/rsmp/component.rb +2 -0
- data/lib/rsmp/{site_base.rb → components.rb} +3 -3
- data/lib/rsmp/convert/export/json_schema.rb +204 -0
- data/lib/rsmp/convert/import/yaml.rb +38 -0
- data/lib/rsmp/deep_merge.rb +11 -0
- data/lib/rsmp/inspect.rb +46 -0
- data/lib/rsmp/listener.rb +23 -0
- data/lib/rsmp/logger.rb +6 -4
- data/lib/rsmp/{base.rb → logging.rb} +3 -3
- data/lib/rsmp/message.rb +22 -31
- data/lib/rsmp/node.rb +15 -7
- data/lib/rsmp/notifier.rb +29 -0
- data/lib/rsmp/proxy.rb +114 -38
- data/lib/rsmp/rsmp.rb +34 -23
- data/lib/rsmp/site.rb +32 -34
- data/lib/rsmp/site_proxy.rb +160 -97
- data/lib/rsmp/site_proxy_wait.rb +206 -0
- data/lib/rsmp/supervisor.rb +82 -47
- data/lib/rsmp/supervisor_proxy.rb +21 -14
- data/lib/rsmp/tlc.rb +80 -38
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp/wait.rb +4 -151
- data/rsmp.gemspec +4 -15
- metadata +27 -124
- data/config/site.yaml +0 -40
- data/lib/rsmp/probe.rb +0 -101
- data/lib/rsmp/probe_collection.rb +0 -28
data/lib/rsmp/logger.rb
CHANGED
@@ -13,6 +13,7 @@ module RSMP
|
|
13
13
|
'component'=>false,
|
14
14
|
'level'=>false,
|
15
15
|
'ip'=>false,
|
16
|
+
'port'=>false,
|
16
17
|
'index'=>false,
|
17
18
|
'timestamp'=>true,
|
18
19
|
'json'=>false,
|
@@ -82,7 +83,6 @@ module RSMP
|
|
82
83
|
end
|
83
84
|
|
84
85
|
def colorize level, str
|
85
|
-
#p String.color_samples
|
86
86
|
if @settings["color"] == false || @settings["color"] == nil
|
87
87
|
str
|
88
88
|
elsif @settings["color"] == true
|
@@ -125,8 +125,9 @@ module RSMP
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
-
def dump archive, force:false
|
129
|
-
|
128
|
+
def dump archive, force:false, num:nil
|
129
|
+
num ||= archive.items.size
|
130
|
+
log = archive.items.last(num).map do |item|
|
130
131
|
str = build_output item
|
131
132
|
str = colorize item[:level], str
|
132
133
|
end
|
@@ -137,8 +138,9 @@ module RSMP
|
|
137
138
|
parts = []
|
138
139
|
parts << item[:index].to_s.ljust(7) if @settings["index"] == true
|
139
140
|
parts << item[:author].to_s.ljust(13) if @settings["author"] == true
|
140
|
-
parts << item[:timestamp].
|
141
|
+
parts << Clock.to_s(item[:timestamp]).ljust(24) unless @settings["timestamp"] == false
|
141
142
|
parts << item[:ip].to_s.ljust(22) unless @settings["ip"] == false
|
143
|
+
parts << item[:port].to_s.ljust(8) unless @settings["port"] == false
|
142
144
|
parts << item[:site_id].to_s.ljust(13) unless @settings["site_id"] == false
|
143
145
|
parts << item[:component_id].to_s.ljust(18) unless @settings["component"] == false
|
144
146
|
|
@@ -3,10 +3,10 @@
|
|
3
3
|
#
|
4
4
|
|
5
5
|
module RSMP
|
6
|
-
|
6
|
+
module Logging
|
7
7
|
attr_reader :archive, :logger
|
8
8
|
|
9
|
-
def
|
9
|
+
def initialize_logging options
|
10
10
|
@archive = options[:archive] || RSMP::Archive.new
|
11
11
|
@logger = options[:logger] || RSMP::Logger.new(options[:log_settings])
|
12
12
|
end
|
@@ -15,7 +15,7 @@ module RSMP
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def log str, options={}
|
18
|
-
default = { str:str, level: :log, author: author }
|
18
|
+
default = { str:str, level: :log, author: author, ip: @ip, port: @port }
|
19
19
|
prepared = RSMP::Archive.prepare_item default.merge(options)
|
20
20
|
@archive.add prepared
|
21
21
|
@logger.log prepared
|
data/lib/rsmp/message.rb
CHANGED
@@ -1,32 +1,14 @@
|
|
1
|
+
require 'rsmp_schemer'
|
2
|
+
|
1
3
|
# rsmp messages
|
2
4
|
module RSMP
|
3
5
|
class Message
|
6
|
+
include Inspect
|
4
7
|
|
5
|
-
attr_reader :now, :attributes, :out
|
8
|
+
attr_reader :now, :attributes, :out
|
9
|
+
attr_reader :timestamp # this is an internal timestamp recording when we receive/send
|
6
10
|
attr_accessor :json, :direction
|
7
11
|
|
8
|
-
def self.load_schemas
|
9
|
-
# path to files in submodule folder
|
10
|
-
schema_path = File.join(File.dirname(__dir__),'rsmp_schema','schema')
|
11
|
-
@@schemas = {}
|
12
|
-
|
13
|
-
core_schema_path = File.join(schema_path,'core','rsmp.json')
|
14
|
-
@@schemas[nil] = JSONSchemer.schema( Pathname.new(core_schema_path) )
|
15
|
-
|
16
|
-
tlc_schema_path = File.join(schema_path,'tlc','sxl.json')
|
17
|
-
@@schemas['traffic_light_controller'] = JSONSchemer.schema( Pathname.new(tlc_schema_path) )
|
18
|
-
|
19
|
-
@@schemas
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.get_schema sxl=nil
|
23
|
-
schema = @@schemas[sxl]
|
24
|
-
raise SchemaError.new("Unknown schema #{sxl}") unless schema
|
25
|
-
schema
|
26
|
-
end
|
27
|
-
|
28
|
-
@@schemas = load_schemas
|
29
|
-
|
30
12
|
def self.make_m_id
|
31
13
|
SecureRandom.uuid()
|
32
14
|
end
|
@@ -49,6 +31,8 @@ module RSMP
|
|
49
31
|
message = Version.new attributes
|
50
32
|
when "AggregatedStatus"
|
51
33
|
message = AggregatedStatus.new attributes
|
34
|
+
when "AggregatedStatusRequest"
|
35
|
+
message = AggregatedStatusRequest.new attributes
|
52
36
|
when "Watchdog"
|
53
37
|
message = Watchdog.new attributes
|
54
38
|
when "Alarm"
|
@@ -125,7 +109,9 @@ module RSMP
|
|
125
109
|
end
|
126
110
|
|
127
111
|
def initialize attributes = {}
|
128
|
-
@timestamp =
|
112
|
+
@timestamp = Time.now # this timestamp is for internal use, and does not the clock
|
113
|
+
# in the node, which can be set by an rsmp supervisor
|
114
|
+
|
129
115
|
@attributes = { "mType"=> "rSMsg" }.merge attributes
|
130
116
|
|
131
117
|
ensure_message_id
|
@@ -136,13 +122,10 @@ module RSMP
|
|
136
122
|
@attributes["mId"] ||= Message.make_m_id
|
137
123
|
end
|
138
124
|
|
139
|
-
def validate
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
error_string = errors.map do |item|
|
144
|
-
[item['data_pointer'],item['type'],item['details']].compact.join(' ')
|
145
|
-
end.join(", ")
|
125
|
+
def validate schemas
|
126
|
+
errors = RSMP::Schemer.validate attributes, schemas
|
127
|
+
if errors
|
128
|
+
error_string = errors.compact.join(', ').strip
|
146
129
|
raise SchemaError.new error_string
|
147
130
|
end
|
148
131
|
end
|
@@ -196,6 +179,14 @@ module RSMP
|
|
196
179
|
end
|
197
180
|
end
|
198
181
|
|
182
|
+
class AggregatedStatusRequest < Message
|
183
|
+
def initialize attributes = {}
|
184
|
+
super({
|
185
|
+
"type" => "AggregatedStatusRequest",
|
186
|
+
}.merge attributes)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
199
190
|
class Alarm < Message
|
200
191
|
def initialize attributes = {}
|
201
192
|
super({
|
data/lib/rsmp/node.rb
CHANGED
@@ -1,18 +1,26 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Handles a single connection to a supervisor.
|
4
|
-
# We connect to the supervisor.
|
1
|
+
# Base class for sites and supervisors
|
5
2
|
|
6
3
|
module RSMP
|
7
|
-
class Node
|
4
|
+
class Node
|
5
|
+
include Logging
|
8
6
|
include Wait
|
7
|
+
include Inspect
|
9
8
|
|
10
|
-
attr_reader :archive, :logger, :task, :deferred
|
9
|
+
attr_reader :archive, :logger, :task, :deferred, :error_condition, :clock
|
11
10
|
|
12
11
|
def initialize options
|
13
|
-
|
12
|
+
initialize_logging options
|
14
13
|
@task = options[:task]
|
15
14
|
@deferred = []
|
15
|
+
@clock = Clock.new
|
16
|
+
@error_condition = Async::Notification.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def notify_error e, options={}
|
20
|
+
if options[:level] == :internal
|
21
|
+
log ["#{e.to_s} in task: #{Async::Task.current.to_s}",e.backtrace].flatten.join("\n"), level: :error
|
22
|
+
end
|
23
|
+
@error_condition.signal e
|
16
24
|
end
|
17
25
|
|
18
26
|
def defer item
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Distributes messages to listeners
|
2
|
+
|
3
|
+
module RSMP
|
4
|
+
module Notifier
|
5
|
+
include Inspect
|
6
|
+
|
7
|
+
def inspect
|
8
|
+
"#<#{self.class.name}:#{self.object_id}, #{inspector(:@listeners)}>"
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_distributor
|
12
|
+
@listeners = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_listener listener
|
16
|
+
raise ArgumentError unless listener
|
17
|
+
@listeners << listener unless @listeners.include? listener
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove_listener listener
|
21
|
+
raise ArgumentError unless listener
|
22
|
+
@listeners.delete listener
|
23
|
+
end
|
24
|
+
|
25
|
+
def notify message
|
26
|
+
@listeners.each { |listener| listener.notify message }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/rsmp/proxy.rb
CHANGED
@@ -1,25 +1,60 @@
|
|
1
|
-
#
|
1
|
+
# Logging class for a connection to a remote site or supervisor.
|
2
|
+
|
3
|
+
require 'rubygems'
|
2
4
|
|
3
5
|
module RSMP
|
4
|
-
class Proxy
|
6
|
+
class Proxy
|
7
|
+
WRAPPING_DELIMITER = "\f"
|
8
|
+
|
9
|
+
include Logging
|
5
10
|
include Wait
|
11
|
+
include Notifier
|
12
|
+
include Inspect
|
6
13
|
|
7
|
-
attr_reader :state, :archive, :connection_info, :sxl, :task
|
14
|
+
attr_reader :state, :archive, :connection_info, :sxl, :task, :collector
|
8
15
|
|
9
16
|
def initialize options
|
10
|
-
|
17
|
+
initialize_logging options
|
11
18
|
@settings = options[:settings]
|
12
19
|
@task = options[:task]
|
13
20
|
@socket = options[:socket]
|
14
21
|
@ip = options[:ip]
|
22
|
+
@port = options[:port]
|
15
23
|
@connection_info = options[:info]
|
16
24
|
@sxl = nil
|
25
|
+
@site_settings = nil # can't pick until we know the site id
|
26
|
+
initialize_distributor
|
27
|
+
|
28
|
+
prepare_collection @settings['collect']
|
17
29
|
clear
|
18
30
|
end
|
19
31
|
|
32
|
+
def inspect
|
33
|
+
"#<#{self.class.name}:#{self.object_id}, #{inspector(
|
34
|
+
:@acknowledgements,:@settings,:@site_settings
|
35
|
+
)}>"
|
36
|
+
end
|
37
|
+
|
38
|
+
def clock
|
39
|
+
node.clock
|
40
|
+
end
|
41
|
+
|
42
|
+
def prepare_collection num
|
43
|
+
if num
|
44
|
+
@collector = RSMP::Collector.new self, num: num, ingoing: true, outgoing: true
|
45
|
+
add_listener @collector
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def collect task, options, &block
|
50
|
+
collector = RSMP::Collector.new self, options
|
51
|
+
collector.collect task, &block
|
52
|
+
end
|
53
|
+
|
20
54
|
def run
|
21
55
|
start
|
22
56
|
@reader.wait if @reader
|
57
|
+
ensure
|
23
58
|
stop unless [:stopped, :stopping].include? @state
|
24
59
|
end
|
25
60
|
|
@@ -71,7 +106,7 @@ module RSMP
|
|
71
106
|
@reader = @task.async do |task|
|
72
107
|
task.annotate "reader"
|
73
108
|
@stream = Async::IO::Stream.new(@socket)
|
74
|
-
@protocol = Async::IO::Protocol::Line.new(@stream,
|
109
|
+
@protocol = Async::IO::Protocol::Line.new(@stream,WRAPPING_DELIMITER) # rsmp messages are json terminated with a form-feed
|
75
110
|
|
76
111
|
while json = @protocol.read_line
|
77
112
|
beginning = Time.now
|
@@ -99,31 +134,33 @@ module RSMP
|
|
99
134
|
log "Connection reset by peer", level: :warning
|
100
135
|
rescue Errno::EPIPE
|
101
136
|
log "Broken pipe", level: :warning
|
102
|
-
rescue SystemCallError => e # all ERRNO errors
|
103
|
-
log "Proxy exception: #{e.to_s}", level: :error
|
104
137
|
rescue StandardError => e
|
105
|
-
|
138
|
+
notify_error e, level: :internal
|
106
139
|
end
|
107
140
|
end
|
108
141
|
|
142
|
+
def notify_error e, options={}
|
143
|
+
node.notify_error e, options
|
144
|
+
end
|
145
|
+
|
109
146
|
def start_watchdog
|
110
|
-
log "Starting watchdog with interval #{@
|
147
|
+
log "Starting watchdog with interval #{@site_settings['intervals']['watchdog']} seconds", level: :debug
|
111
148
|
send_watchdog
|
112
149
|
@watchdog_started = true
|
113
150
|
end
|
114
151
|
|
115
152
|
def start_timer
|
116
153
|
name = "timer"
|
117
|
-
interval = @
|
154
|
+
interval = @site_settings['intervals']['timer'] || 1
|
118
155
|
log "Starting #{name} with interval #{interval} seconds", level: :debug
|
119
|
-
@latest_watchdog_received =
|
156
|
+
@latest_watchdog_received = Clock.now
|
120
157
|
|
121
158
|
@timer = @task.async do |task|
|
122
159
|
task.annotate "timer"
|
123
160
|
next_time = Time.now.to_f
|
124
161
|
loop do
|
125
162
|
begin
|
126
|
-
now =
|
163
|
+
now = Clock.now
|
127
164
|
timer(now)
|
128
165
|
rescue EOFError => e
|
129
166
|
log "Timer: Connection closed: #{e}", level: :warning
|
@@ -134,9 +171,7 @@ module RSMP
|
|
134
171
|
rescue Errno::EPIPE => e
|
135
172
|
log "Timer: Broken pipe", level: :warning
|
136
173
|
rescue StandardError => e
|
137
|
-
|
138
|
-
#rescue StandardError => e
|
139
|
-
# log ["Timer error: #{e}",e.backtrace].flatten.join("\n"), level: :error
|
174
|
+
notify_error e, level: :internal
|
140
175
|
end
|
141
176
|
ensure
|
142
177
|
next_time += interval
|
@@ -154,7 +189,7 @@ module RSMP
|
|
154
189
|
|
155
190
|
def watchdog_send_timer now
|
156
191
|
return unless @watchdog_started
|
157
|
-
return if @
|
192
|
+
return if @site_settings['intervals']['watchdog'] == :never
|
158
193
|
|
159
194
|
if @latest_watchdog_send_at == nil
|
160
195
|
send_watchdog now
|
@@ -162,21 +197,20 @@ module RSMP
|
|
162
197
|
# we add half the timer interval to pick the timer
|
163
198
|
# event closes to the wanted wathcdog interval
|
164
199
|
diff = now - @latest_watchdog_send_at
|
165
|
-
if (diff + 0.5*@
|
200
|
+
if (diff + 0.5*@site_settings['intervals']['timer']) >= (@site_settings['intervals']['watchdog'])
|
166
201
|
send_watchdog now
|
167
202
|
end
|
168
203
|
end
|
169
204
|
end
|
170
205
|
|
171
|
-
def send_watchdog now=
|
172
|
-
|
173
|
-
message = Watchdog.new( {"wTs" => RSMP.now_object_to_string(now)})
|
206
|
+
def send_watchdog now=Clock.now
|
207
|
+
message = Watchdog.new( {"wTs" => clock.to_s})
|
174
208
|
send_message message
|
175
209
|
@latest_watchdog_send_at = now
|
176
210
|
end
|
177
211
|
|
178
212
|
def check_ack_timeout now
|
179
|
-
timeout = @
|
213
|
+
timeout = @site_settings['timeouts']['acknowledgement']
|
180
214
|
# hash cannot be modify during iteration, so clone it
|
181
215
|
@awaiting_acknowledgement.clone.each_pair do |m_id, message|
|
182
216
|
latest = message.timestamp + timeout
|
@@ -188,7 +222,7 @@ module RSMP
|
|
188
222
|
end
|
189
223
|
|
190
224
|
def check_watchdog_timeout now
|
191
|
-
timeout = @
|
225
|
+
timeout = @site_settings['timeouts']['watchdog']
|
192
226
|
latest = @latest_watchdog_received + timeout
|
193
227
|
left = latest - now
|
194
228
|
if left < 0
|
@@ -206,18 +240,31 @@ module RSMP
|
|
206
240
|
super str, options.merge(ip: @ip, port: @port, site_id: @site_id)
|
207
241
|
end
|
208
242
|
|
209
|
-
def
|
243
|
+
def get_schemas
|
244
|
+
# normally we have an sxl, but during connection, it hasn't been established yet
|
245
|
+
# at these times we only validate against the core schema
|
246
|
+
# TODO
|
247
|
+
# what schema should we use to validate the intial Version and MessageAck messages?
|
248
|
+
schemas = { core: '3.1.5' }
|
249
|
+
schemas[sxl] = sxl_version if sxl
|
250
|
+
schemas
|
251
|
+
end
|
252
|
+
|
253
|
+
def send_message message, reason=nil, validate: true
|
210
254
|
raise IOError unless @protocol
|
211
|
-
message.generate_json
|
212
|
-
message.validate sxl
|
213
255
|
message.direction = :out
|
256
|
+
message.generate_json
|
257
|
+
message.validate get_schemas unless validate==false
|
214
258
|
expect_acknowledgement message
|
215
259
|
@protocol.write_lines message.json
|
260
|
+
notify message
|
216
261
|
log_send message, reason
|
217
262
|
rescue EOFError, IOError
|
218
263
|
buffer_message message
|
219
264
|
rescue SchemaError => e
|
220
|
-
|
265
|
+
str = "Could not send #{message.type} because schema validation failed: #{e.message}"
|
266
|
+
log str, message: message, level: :error
|
267
|
+
notify_error e.exception("#{str} #{message.json}")
|
221
268
|
end
|
222
269
|
|
223
270
|
def buffer_message message
|
@@ -242,26 +289,38 @@ module RSMP
|
|
242
289
|
def process_packet json
|
243
290
|
attributes = Message.parse_attributes json
|
244
291
|
message = Message.build attributes, json
|
245
|
-
message.validate
|
292
|
+
message.validate get_schemas
|
293
|
+
notify message
|
246
294
|
expect_version_message(message) unless @version_determined
|
247
295
|
process_message message
|
248
296
|
process_deferred
|
249
297
|
message
|
250
298
|
rescue InvalidPacket => e
|
251
|
-
|
299
|
+
str = "Received invalid package, must be valid JSON but got #{json.size} bytes: #{e.message}"
|
300
|
+
notify_error e.exception(str)
|
301
|
+
log str, level: :warning
|
252
302
|
nil
|
253
303
|
rescue MalformedMessage => e
|
254
|
-
|
304
|
+
str = "Received malformed message, #{e.message}"
|
305
|
+
notify_error e.exception(str)
|
306
|
+
log str, message: Malformed.new(attributes), level: :warning
|
255
307
|
# cannot send NotAcknowledged for a malformed message since we can't read it, just ignore it
|
256
308
|
nil
|
257
309
|
rescue SchemaError => e
|
258
|
-
|
310
|
+
str = "Received invalid #{message.type}, schema errors: #{e.message}"
|
311
|
+
log str, message: message, level: :warning
|
312
|
+
notify_error e.exception("#{str} #{message.json}")
|
313
|
+
dont_acknowledge message, str
|
259
314
|
message
|
260
315
|
rescue InvalidMessage => e
|
261
|
-
|
316
|
+
str = "Received", "invalid #{message.type}, #{e.message}"
|
317
|
+
notify_error e.exception("#{str} #{message.json}")
|
318
|
+
dont_acknowledge message, str
|
262
319
|
message
|
263
320
|
rescue FatalError => e
|
264
|
-
|
321
|
+
str = "Rejected #{message.type},"
|
322
|
+
notify_error e.exception("#{str} #{message.json}")
|
323
|
+
dont_acknowledge message, str, "#{e.message}"
|
265
324
|
stop
|
266
325
|
message
|
267
326
|
end
|
@@ -301,13 +360,20 @@ module RSMP
|
|
301
360
|
dont_acknowledge message, "Received", "extraneous Version message"
|
302
361
|
end
|
303
362
|
|
363
|
+
def rsmp_versions
|
364
|
+
return ['3.1.5'] if @site_settings["rsmp_versions"] == 'latest'
|
365
|
+
return ['3.1.1','3.1.2','3.1.3','3.1.4','3.1.5'] if @site_settings["rsmp_versions"] == 'all'
|
366
|
+
@site_settings["rsmp_versions"]
|
367
|
+
end
|
368
|
+
|
304
369
|
def check_rsmp_version message
|
370
|
+
versions = rsmp_versions
|
305
371
|
# find versions that both we and the client support
|
306
|
-
candidates = message.versions &
|
372
|
+
candidates = message.versions & versions
|
307
373
|
if candidates.any?
|
308
|
-
@rsmp_version = candidates.
|
374
|
+
@rsmp_version = candidates.sort_by { |v| Gem::Version.new(v) }.last # pick latest version
|
309
375
|
else
|
310
|
-
raise FatalError.new "RSMP versions [#{message.versions.join(',')}] requested, but only [#{
|
376
|
+
raise FatalError.new "RSMP versions [#{message.versions.join(',')}] requested, but only [#{versions.join(',')}] supported."
|
311
377
|
end
|
312
378
|
end
|
313
379
|
|
@@ -342,14 +408,24 @@ module RSMP
|
|
342
408
|
def wait_for_state state, timeout
|
343
409
|
states = [state].flatten
|
344
410
|
return if states.include?(@state)
|
345
|
-
wait_for(@state_condition,timeout) do
|
411
|
+
wait_for(@state_condition,timeout) do
|
346
412
|
states.include?(@state)
|
347
413
|
end
|
348
414
|
@state
|
415
|
+
rescue Async::TimeoutError
|
416
|
+
raise RSMP::TimeoutError.new "Did not reach state #{state} within #{timeout}s"
|
349
417
|
end
|
350
418
|
|
351
419
|
def send_version site_id, rsmp_versions
|
352
|
-
|
420
|
+
if rsmp_versions=='latest'
|
421
|
+
versions = ['3.1.5']
|
422
|
+
elsif rsmp_versions=='all'
|
423
|
+
versions = ['3.1.1','3.1.2','3.1.3','3.1.4','3.1.5']
|
424
|
+
else
|
425
|
+
versions = [rsmp_versions].flatten
|
426
|
+
end
|
427
|
+
versions_array = versions.map {|v| {"vers" => v} }
|
428
|
+
|
353
429
|
site_id_array = [site_id].flatten.map {|id| {"sId" => id} }
|
354
430
|
|
355
431
|
version_response = Version.new({
|
@@ -435,7 +511,7 @@ module RSMP
|
|
435
511
|
|
436
512
|
def process_watchdog message
|
437
513
|
log "Received #{message.type}", message: message, level: :log
|
438
|
-
@latest_watchdog_received =
|
514
|
+
@latest_watchdog_received = Clock.now
|
439
515
|
acknowledge message
|
440
516
|
end
|
441
517
|
|