rsmp 0.4.5 → 0.5.2
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 +1 -1
- data/config/supervisor.yaml +1 -0
- data/config/tlc.yaml +1 -0
- data/lib/rsmp/collect/collector.rb +44 -2
- data/lib/rsmp/collect/listener.rb +3 -0
- data/lib/rsmp/collect/matcher.rb +0 -1
- data/lib/rsmp/collect/notifier.rb +29 -0
- data/lib/rsmp/component.rb +75 -0
- data/lib/rsmp/error.rb +6 -0
- data/lib/rsmp/logger.rb +4 -1
- data/lib/rsmp/message.rb +1 -1
- data/lib/rsmp/proxy.rb +22 -11
- data/lib/rsmp/site_proxy.rb +19 -12
- data/lib/rsmp/supervisor.rb +9 -5
- data/lib/rsmp/supervisor_proxy.rb +9 -17
- data/lib/rsmp/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9551219e8b4223f7d3fc615efe9a6e0c648b930c30e023426a4fafd60e15cdc8
|
4
|
+
data.tar.gz: 859c020b24d0065d692cbba2ae1cb8de4a3498a03cd6d888fbdf8dab88e90491
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d5817111ffefe2cef5bc11a66872ef473203eeacd12fbb59c2c001cdb461b8d53cb7965855449083bf7db7225a2390eac4d5f49227c9d8bafa9285a40332837
|
7
|
+
data.tar.gz: 85d4bea87373f4d65efd271877627d2be1eb43fc3c75368e312ab2942a3e8db99e512fd2be0351d1add466a43b87c3f8a5477ccb7d72ee9487dd932c43bbaca6
|
data/Gemfile.lock
CHANGED
data/config/supervisor.yaml
CHANGED
data/config/tlc.yaml
CHANGED
@@ -7,7 +7,12 @@ module RSMP
|
|
7
7
|
|
8
8
|
def initialize proxy, options={}
|
9
9
|
super proxy, options
|
10
|
-
@options =
|
10
|
+
@options = {
|
11
|
+
cancel: {
|
12
|
+
schema_error: true,
|
13
|
+
disconnect: false,
|
14
|
+
}
|
15
|
+
}.deep_merge options
|
11
16
|
@ingoing = options[:ingoing] == nil ? true : options[:ingoing]
|
12
17
|
@outgoing = options[:outgoing] == nil ? false : options[:outgoing]
|
13
18
|
@condition = Async::Notification.new
|
@@ -82,7 +87,7 @@ module RSMP
|
|
82
87
|
if message.is_a?(MessageNotAck)
|
83
88
|
if message.attribute('oMId') == @options[:m_id]
|
84
89
|
m_id_short = RSMP::Message.shorten_m_id @options[:m_id], 8
|
85
|
-
@error = RSMP::MessageRejected.new("#{@title} #{m_id_short} was rejected
|
90
|
+
@error = RSMP::MessageRejected.new("#{@title} #{m_id_short} was rejected with '#{message.attribute('rea')}'")
|
86
91
|
complete
|
87
92
|
end
|
88
93
|
false
|
@@ -123,6 +128,43 @@ module RSMP
|
|
123
128
|
@condition.signal
|
124
129
|
end
|
125
130
|
|
131
|
+
# The proxy experienced some error.
|
132
|
+
# Check if this should cause us to cancel.
|
133
|
+
def notify_error error, options={}
|
134
|
+
case error
|
135
|
+
when RSMP::SchemaError
|
136
|
+
notify_schema_error error, options
|
137
|
+
when RSMP::ConnectionError
|
138
|
+
notify_disconnect error, options
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Cancel if we received e schema error for a message type we're collecting
|
143
|
+
def notify_schema_error error, options
|
144
|
+
return unless @options.dig(:cancel,:schema_error)
|
145
|
+
message = options[:message]
|
146
|
+
return unless message
|
147
|
+
klass = message.class.name.split('::').last
|
148
|
+
return unless [@options[:type]].flatten.include? klass
|
149
|
+
@proxy.log "Collect cancelled due to schema error in #{klass} #{message.m_id_short}", level: :debug
|
150
|
+
cancel error
|
151
|
+
end
|
152
|
+
|
153
|
+
# Cancel if we received e notificaiton about a disconnect
|
154
|
+
def notify_disconnect error, options
|
155
|
+
return unless @options.dig(:cancel,:disconnect)
|
156
|
+
@proxy.log "Collect cancelled due to a connection error: #{error.to_s}", level: :debug
|
157
|
+
cancel error
|
158
|
+
end
|
159
|
+
|
160
|
+
# Abort collection
|
161
|
+
def cancel error
|
162
|
+
@error = error if error
|
163
|
+
@done = false
|
164
|
+
@proxy.remove_listener self
|
165
|
+
@condition.signal
|
166
|
+
end
|
167
|
+
|
126
168
|
# Store a message in the result array
|
127
169
|
def keep message
|
128
170
|
@messages << message
|
data/lib/rsmp/collect/matcher.rb
CHANGED
@@ -12,6 +12,22 @@ module RSMP
|
|
12
12
|
|
13
13
|
def initialize_distributor
|
14
14
|
@listeners = []
|
15
|
+
@defer_notify = false
|
16
|
+
@notify_queue = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def deferred_notify &block
|
20
|
+
was, @defer_notify = @defer_notify, true
|
21
|
+
yield
|
22
|
+
dequeue_notify
|
23
|
+
ensure
|
24
|
+
@defer_notify = was
|
25
|
+
end
|
26
|
+
|
27
|
+
def dequeue_notify
|
28
|
+
@notify_queue.each { |message| notify_without_defer message }
|
29
|
+
ensure
|
30
|
+
@notify_queue = []
|
15
31
|
end
|
16
32
|
|
17
33
|
def add_listener listener
|
@@ -25,7 +41,20 @@ module RSMP
|
|
25
41
|
end
|
26
42
|
|
27
43
|
def notify message
|
44
|
+
raise ArgumentError unless message
|
45
|
+
if @defer_notify
|
46
|
+
@notify_queue << message
|
47
|
+
else
|
48
|
+
notify_without_defer message
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def notify_without_defer message
|
28
53
|
@listeners.each { |listener| listener.notify message }
|
29
54
|
end
|
55
|
+
|
56
|
+
def distribute_error error, options={}
|
57
|
+
@listeners.each { |listener| listener.notify_error error, options }
|
58
|
+
end
|
30
59
|
end
|
31
60
|
end
|
data/lib/rsmp/component.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
module RSMP
|
2
|
+
|
3
|
+
# Class that represents an RMSP component.
|
4
|
+
# Currently this class is used by both SiteProxy and SupervisorProxy, and can
|
5
|
+
# therefore represent either a local or remote (proxy) component.
|
6
|
+
|
2
7
|
class Component
|
3
8
|
include Inspect
|
4
9
|
|
@@ -19,6 +24,7 @@ module RSMP
|
|
19
24
|
@grouped = grouped
|
20
25
|
@alarms = {}
|
21
26
|
@statuses = {}
|
27
|
+
@subscribes = {}
|
22
28
|
clear_aggregated_status
|
23
29
|
end
|
24
30
|
|
@@ -83,5 +89,74 @@ module RSMP
|
|
83
89
|
@alarms[code] = message
|
84
90
|
end
|
85
91
|
end
|
92
|
+
|
93
|
+
# Handle an incoming status respone, by storing the values
|
94
|
+
def handle_status_response message
|
95
|
+
store_status message, check_repeated: false
|
96
|
+
end
|
97
|
+
|
98
|
+
# Handle an incoming status update, by storing the values
|
99
|
+
def handle_status_update message
|
100
|
+
store_status message, check_repeated: true
|
101
|
+
end
|
102
|
+
|
103
|
+
# Our proxy subscribed to status updates
|
104
|
+
# Store update rates, so we can check for repeated alarm if we asked for updates only
|
105
|
+
# when there's a change, not on a regular interval.
|
106
|
+
# After subscribing, an update status us send regarless of whether values changes,
|
107
|
+
# and we store that.
|
108
|
+
def handle_status_subscribe status_list
|
109
|
+
status_list.each do |item|
|
110
|
+
sCI, n, uRt = item['sCI'], item['n'], item['uRt']
|
111
|
+
|
112
|
+
# record the update rate, so we can check for repeated status values if rate is zero
|
113
|
+
@subscribes[sCI] ||= {}
|
114
|
+
@subscribes[sCI][n] = {'uRt'=>uRt}
|
115
|
+
|
116
|
+
# record that we expect an upeate, even though the value might not change
|
117
|
+
@statuses[sCI] ||= {}
|
118
|
+
@statuses[sCI][n] ||= {}
|
119
|
+
@statuses[sCI][n][:initial] = true
|
120
|
+
end
|
121
|
+
#pp @subscribes
|
122
|
+
end
|
123
|
+
|
124
|
+
# Our proxy unsubscribed to status updates.
|
125
|
+
# Update our list of update rates.
|
126
|
+
def handle_status_unsubscribe status_list
|
127
|
+
status_list.each do |item|
|
128
|
+
sCI, n = item['sCI'], item['n']
|
129
|
+
if @subscribes[sCI]
|
130
|
+
@subscribes[sCI].delete n
|
131
|
+
end
|
132
|
+
if @subscribes[sCI].empty?
|
133
|
+
@subscribes.delete sCI
|
134
|
+
end
|
135
|
+
|
136
|
+
# remove any mark that would allow the next update to be a repeat
|
137
|
+
item = @statuses.dig sCI, n
|
138
|
+
item.delete(:initial) if item
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Store the latest status update values, optionally
|
143
|
+
# checking that we're not receiving unchanged values if we're subscribed
|
144
|
+
# wit updates only on change
|
145
|
+
def store_status message, check_repeated:
|
146
|
+
message.attribute('sS').each do |item|
|
147
|
+
sCI, n, s, q = item['sCI'], item['n'], item['s'], item['q']
|
148
|
+
uRt = @subscribes.dig(sCI,n,'uRt')
|
149
|
+
new_values = {'s'=>s,'q'=>q}
|
150
|
+
old_values = @statuses.dig(sCI,n)
|
151
|
+
if check_repeated && uRt.to_i == 0
|
152
|
+
if new_values == old_values
|
153
|
+
raise RSMP::RepeatedStatusError.new "no change for #{sCI} '#{n}'"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
@statuses[sCI] ||= {}
|
157
|
+
@statuses[sCI][n] = new_values
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
86
161
|
end
|
87
162
|
end
|
data/lib/rsmp/error.rb
CHANGED
@@ -32,6 +32,9 @@ module RSMP
|
|
32
32
|
class FatalError < Error
|
33
33
|
end
|
34
34
|
|
35
|
+
class HandshakeError < FatalError
|
36
|
+
end
|
37
|
+
|
35
38
|
class NotReady < Error
|
36
39
|
end
|
37
40
|
|
@@ -55,4 +58,7 @@ module RSMP
|
|
55
58
|
|
56
59
|
class RepeatedAlarmError < Error
|
57
60
|
end
|
61
|
+
|
62
|
+
class RepeatedStatusError < Error
|
63
|
+
end
|
58
64
|
end
|
data/lib/rsmp/logger.rb
CHANGED
@@ -5,6 +5,7 @@ module RSMP
|
|
5
5
|
|
6
6
|
def initialize settings={}
|
7
7
|
defaults = {
|
8
|
+
'prefix'=>nil,
|
8
9
|
'active'=>false,
|
9
10
|
'path'=>nil,
|
10
11
|
'stream'=>nil,
|
@@ -20,7 +21,8 @@ module RSMP
|
|
20
21
|
'json'=>false,
|
21
22
|
'debug'=>false,
|
22
23
|
'statistics'=>false,
|
23
|
-
'hide_ip_and_port' => false
|
24
|
+
'hide_ip_and_port' => false,
|
25
|
+
'acknowledgements' => false
|
24
26
|
}
|
25
27
|
if settings
|
26
28
|
@settings = defaults.merge settings
|
@@ -139,6 +141,7 @@ module RSMP
|
|
139
141
|
|
140
142
|
def build_output item
|
141
143
|
parts = []
|
144
|
+
parts << "#{@settings['prefix']} " if @settings['prefix']
|
142
145
|
parts << item[:index].to_s.ljust(7) if @settings["index"] == true
|
143
146
|
parts << item[:author].to_s.ljust(13) if @settings["author"] == true
|
144
147
|
parts << Clock.to_s(item[:timestamp]).ljust(24) unless @settings["timestamp"] == false
|
data/lib/rsmp/message.rb
CHANGED
@@ -142,7 +142,7 @@ module RSMP
|
|
142
142
|
def validate schemas
|
143
143
|
errors = RSMP::Schemer.validate attributes, schemas
|
144
144
|
if errors
|
145
|
-
error_string = errors.compact.join(', ').strip
|
145
|
+
error_string = errors.map {|item| item.reject {|e| e=='' } }.compact.join(', ').strip
|
146
146
|
raise SchemaError.new error_string
|
147
147
|
end
|
148
148
|
end
|
data/lib/rsmp/proxy.rb
CHANGED
@@ -86,6 +86,7 @@ module RSMP
|
|
86
86
|
return if @state == :stopped
|
87
87
|
set_state :stopping
|
88
88
|
stop_tasks
|
89
|
+
notify_error ConnectionError.new("Connection was closed")
|
89
90
|
ensure
|
90
91
|
close_socket
|
91
92
|
clear
|
@@ -237,6 +238,7 @@ module RSMP
|
|
237
238
|
if now > latest
|
238
239
|
log "No acknowledgements for #{message.type} #{message.m_id_short} within #{timeout} seconds", level: :error
|
239
240
|
stop
|
241
|
+
notify_error MissingAcknowledgment.new('No ack')
|
240
242
|
end
|
241
243
|
end
|
242
244
|
end
|
@@ -266,7 +268,7 @@ module RSMP
|
|
266
268
|
# TODO
|
267
269
|
# what schema should we use to validate the intial Version and MessageAck messages?
|
268
270
|
schemas = { core: '3.1.5' }
|
269
|
-
schemas[sxl] = RSMP::Schemer.sanitize_version(sxl_version) if sxl
|
271
|
+
schemas[sxl] = RSMP::Schemer.sanitize_version(sxl_version) if sxl && sxl_version
|
270
272
|
schemas
|
271
273
|
end
|
272
274
|
|
@@ -315,13 +317,23 @@ module RSMP
|
|
315
317
|
!skip.include?(klass)
|
316
318
|
end
|
317
319
|
|
320
|
+
def process_deferred
|
321
|
+
node.process_deferred
|
322
|
+
end
|
323
|
+
|
324
|
+
def verify_sequence message
|
325
|
+
expect_version_message(message) unless @version_determined
|
326
|
+
end
|
327
|
+
|
318
328
|
def process_packet json
|
319
329
|
attributes = Message.parse_attributes json
|
320
330
|
message = Message.build attributes, json
|
321
331
|
message.validate(get_schemas) if should_validate_ingoing_message?(message)
|
322
|
-
|
323
|
-
|
324
|
-
|
332
|
+
verify_sequence message
|
333
|
+
deferred_notify do
|
334
|
+
notify message
|
335
|
+
process_message message
|
336
|
+
end
|
325
337
|
process_deferred
|
326
338
|
message
|
327
339
|
rescue InvalidPacket => e
|
@@ -338,17 +350,17 @@ module RSMP
|
|
338
350
|
rescue SchemaError, RSMP::Schemer::Error => e
|
339
351
|
str = "Received invalid #{message.type}, schema errors: #{e.message}"
|
340
352
|
log str, message: message, level: :warning
|
341
|
-
notify_error e.exception("#{str} #{message.json}")
|
353
|
+
notify_error e.exception("#{str} #{message.json}"), message: message
|
342
354
|
dont_acknowledge message, str
|
343
355
|
message
|
344
356
|
rescue InvalidMessage => e
|
345
357
|
str = "Received", "invalid #{message.type}, #{e.message}"
|
346
|
-
notify_error e.exception("#{str} #{message.json}")
|
358
|
+
notify_error e.exception("#{str} #{message.json}"), message: message
|
347
359
|
dont_acknowledge message, str
|
348
360
|
message
|
349
361
|
rescue FatalError => e
|
350
362
|
str = "Rejected #{message.type},"
|
351
|
-
notify_error e.exception("#{str} #{message.json}")
|
363
|
+
notify_error e.exception("#{str} #{message.json}"), message: message
|
352
364
|
dont_acknowledge message, str, "#{e.message}"
|
353
365
|
stop
|
354
366
|
message
|
@@ -402,7 +414,7 @@ module RSMP
|
|
402
414
|
if candidates.any?
|
403
415
|
@rsmp_version = candidates.sort_by { |v| Gem::Version.new(v) }.last # pick latest version
|
404
416
|
else
|
405
|
-
raise
|
417
|
+
raise HandshakeError.new "RSMP versions [#{message.versions.join(',')}] requested, but only [#{versions.join(',')}] supported."
|
406
418
|
end
|
407
419
|
end
|
408
420
|
|
@@ -546,7 +558,7 @@ module RSMP
|
|
546
558
|
|
547
559
|
def expect_version_message message
|
548
560
|
unless message.is_a?(Version) || message.is_a?(MessageAck) || message.is_a?(MessageNotAck)
|
549
|
-
raise
|
561
|
+
raise HandshakeError.new "Version must be received first"
|
550
562
|
end
|
551
563
|
end
|
552
564
|
|
@@ -578,7 +590,7 @@ module RSMP
|
|
578
590
|
# will be raised in the parent task, and caught by rspec.
|
579
591
|
# rspec will then show the error and record the test as failed
|
580
592
|
m_id_short = RSMP::Message.shorten_m_id m_id, 8
|
581
|
-
result = RSMP::MessageRejected.new "Aggregated status request #{m_id_short} was rejected
|
593
|
+
result = RSMP::MessageRejected.new "Aggregated status request #{m_id_short} was rejected with '#{message.attribute('rea')}'"
|
582
594
|
next true # done, no more messages wanted
|
583
595
|
end
|
584
596
|
elsif message.is_a?(MessageAck)
|
@@ -587,6 +599,5 @@ module RSMP
|
|
587
599
|
false
|
588
600
|
end
|
589
601
|
end
|
590
|
-
|
591
602
|
end
|
592
603
|
end
|
data/lib/rsmp/site_proxy.rb
CHANGED
@@ -68,6 +68,10 @@ module RSMP
|
|
68
68
|
else
|
69
69
|
super message
|
70
70
|
end
|
71
|
+
rescue RSMP::RepeatedAlarmError, RSMP::RepeatedStatusError => e
|
72
|
+
str = "Rejected #{message.type} message,"
|
73
|
+
dont_acknowledge message, str, "#{e}"
|
74
|
+
notify_error e.exception("#{str}#{e.message} #{message.json}")
|
71
75
|
end
|
72
76
|
|
73
77
|
def process_command_response message
|
@@ -75,10 +79,6 @@ module RSMP
|
|
75
79
|
acknowledge message
|
76
80
|
end
|
77
81
|
|
78
|
-
def process_deferred
|
79
|
-
supervisor.process_deferred
|
80
|
-
end
|
81
|
-
|
82
82
|
def version_accepted message
|
83
83
|
log "Received Version message for site #{@site_id}", message: message, level: :log
|
84
84
|
start_timer
|
@@ -149,10 +149,6 @@ module RSMP
|
|
149
149
|
asp = message.attribute("aSp")
|
150
150
|
log "Received #{message.type}, #{alarm_code} #{asp} [#{status}]", message: message, level: :log
|
151
151
|
acknowledge message
|
152
|
-
rescue RSMP::RepeatedAlarmError => e
|
153
|
-
str = "Rejected #{message.type} message, "
|
154
|
-
dont_acknowledge message, str, "#{e}"
|
155
|
-
notify_error e.exception("#{str}#{e.message} #{message.json}")
|
156
152
|
end
|
157
153
|
|
158
154
|
def version_acknowledged
|
@@ -191,6 +187,8 @@ module RSMP
|
|
191
187
|
end
|
192
188
|
|
193
189
|
def process_status_response message
|
190
|
+
component = find_component message.attribute("cId")
|
191
|
+
component.handle_status_response message
|
194
192
|
log "Received #{message.type}", message: message, level: :log
|
195
193
|
acknowledge message
|
196
194
|
end
|
@@ -202,7 +200,7 @@ module RSMP
|
|
202
200
|
message
|
203
201
|
end
|
204
202
|
|
205
|
-
def subscribe_to_status
|
203
|
+
def subscribe_to_status component_id, status_list, options={}
|
206
204
|
validate_ready 'subscribe to status'
|
207
205
|
m_id = options[:m_id] || RSMP::Message.make_m_id
|
208
206
|
|
@@ -210,10 +208,13 @@ module RSMP
|
|
210
208
|
# but must to remove from the subscribe message
|
211
209
|
subscribe_list = status_list.map { |item| item.slice('sCI','n','uRt') }
|
212
210
|
|
211
|
+
component = find_component component_id
|
212
|
+
component.handle_status_subscribe subscribe_list
|
213
|
+
|
213
214
|
message = RSMP::StatusSubscribe.new({
|
214
215
|
"ntsOId" => '',
|
215
216
|
"xNId" => '',
|
216
|
-
"cId" =>
|
217
|
+
"cId" => component_id,
|
217
218
|
"sS" => subscribe_list,
|
218
219
|
'mId' => m_id
|
219
220
|
})
|
@@ -222,12 +223,15 @@ module RSMP
|
|
222
223
|
end
|
223
224
|
end
|
224
225
|
|
225
|
-
def unsubscribe_to_status
|
226
|
+
def unsubscribe_to_status component_id, status_list, options={}
|
227
|
+
component = find_component component_id
|
228
|
+
component.handle_status_subscribe status_list
|
229
|
+
|
226
230
|
validate_ready 'unsubscribe to status'
|
227
231
|
message = RSMP::StatusUnsubscribe.new({
|
228
232
|
"ntsOId" => '',
|
229
233
|
"xNId" => '',
|
230
|
-
"cId" =>
|
234
|
+
"cId" => component_id,
|
231
235
|
"sS" => status_list
|
232
236
|
})
|
233
237
|
send_message message, validate: options[:validate]
|
@@ -235,6 +239,8 @@ module RSMP
|
|
235
239
|
end
|
236
240
|
|
237
241
|
def process_status_update message
|
242
|
+
component = find_component message.attribute("cId")
|
243
|
+
component.handle_status_update message
|
238
244
|
log "Received #{message.type}", message: message, level: :log
|
239
245
|
acknowledge message
|
240
246
|
end
|
@@ -333,6 +339,7 @@ module RSMP
|
|
333
339
|
|
334
340
|
def notify_error e, options={}
|
335
341
|
@supervisor.notify_error e, options if @supervisor
|
342
|
+
distribute_error e, options
|
336
343
|
end
|
337
344
|
|
338
345
|
def collect_alarms parent_task, options={}
|
data/lib/rsmp/supervisor.rb
CHANGED
@@ -7,7 +7,7 @@ module RSMP
|
|
7
7
|
attr_reader :rsmp_versions, :site_id, :supervisor_settings, :proxies, :logger
|
8
8
|
|
9
9
|
def initialize options={}
|
10
|
-
handle_supervisor_settings options[:supervisor_settings]
|
10
|
+
handle_supervisor_settings( options[:supervisor_settings] || {} )
|
11
11
|
super options
|
12
12
|
@proxies = []
|
13
13
|
@site_id_condition = Async::Notification.new
|
@@ -17,7 +17,7 @@ module RSMP
|
|
17
17
|
@supervisor_settings['site_id']
|
18
18
|
end
|
19
19
|
|
20
|
-
def handle_supervisor_settings supervisor_settings
|
20
|
+
def handle_supervisor_settings supervisor_settings
|
21
21
|
defaults = {
|
22
22
|
'port' => 12111,
|
23
23
|
'ips' => 'all',
|
@@ -172,7 +172,11 @@ module RSMP
|
|
172
172
|
id = peek_version_message protocol
|
173
173
|
proxy = find_site id
|
174
174
|
if proxy
|
175
|
-
proxy.
|
175
|
+
if proxy.connected?
|
176
|
+
raise ConnectionError.new("Site #{id} alredy connected from port #{proxy.port}")
|
177
|
+
else
|
178
|
+
proxy.revive settings
|
179
|
+
end
|
176
180
|
else
|
177
181
|
check_max_sites
|
178
182
|
proxy = build_proxy settings.merge(site_id:id) # keep the id learned by peeking above
|
@@ -246,7 +250,7 @@ module RSMP
|
|
246
250
|
|
247
251
|
def check_site_already_connected site_id
|
248
252
|
site = find_site(site_id)
|
249
|
-
raise
|
253
|
+
raise HandshakeError.new "Site '#{site_id}' already connected" if site != nil && site != self
|
250
254
|
end
|
251
255
|
|
252
256
|
def site_id_to_site_setting site_id
|
@@ -256,7 +260,7 @@ module RSMP
|
|
256
260
|
return settings
|
257
261
|
end
|
258
262
|
end
|
259
|
-
raise
|
263
|
+
raise HandshakeError.new "site id #{site_id} unknown"
|
260
264
|
end
|
261
265
|
|
262
266
|
def ip_to_site_settings ip
|
@@ -86,10 +86,6 @@ module RSMP
|
|
86
86
|
dont_acknowledge message, '', e.to_s
|
87
87
|
end
|
88
88
|
|
89
|
-
def process_deferred
|
90
|
-
site.process_deferred
|
91
|
-
end
|
92
|
-
|
93
89
|
def acknowledged_first_ingoing message
|
94
90
|
# TODO
|
95
91
|
# aggregateds status should only be send for later version of rsmp
|
@@ -229,7 +225,6 @@ module RSMP
|
|
229
225
|
def process_status_subcribe message
|
230
226
|
log "Received #{message.type}", message: message, level: :log
|
231
227
|
|
232
|
-
|
233
228
|
# @status_subscriptions is organized by component/code/name, for example:
|
234
229
|
#
|
235
230
|
# {"AA+BBCCC=DDDEE002"=>{"S001"=>["number"]}}
|
@@ -238,21 +233,14 @@ module RSMP
|
|
238
233
|
# for each component, containing all the requested statuses
|
239
234
|
|
240
235
|
update_list = {}
|
241
|
-
|
242
236
|
component = message.attributes["cId"]
|
243
|
-
|
244
237
|
@status_subscriptions[component] ||= {}
|
245
238
|
update_list[component] ||= {}
|
246
|
-
|
247
|
-
subs = @status_subscriptions[component]
|
248
239
|
now = Time.now # internal timestamp
|
249
240
|
|
250
241
|
message.attributes["sS"].each do |arg|
|
251
242
|
sCI = arg["sCI"]
|
252
243
|
subcription = {interval: arg["uRt"].to_i, last_sent_at: now}
|
253
|
-
subs[sCI] ||= {}
|
254
|
-
subs[sCI][arg["n"]] = subcription
|
255
|
-
|
256
244
|
update_list[component][sCI] ||= []
|
257
245
|
update_list[component][sCI] << arg["n"]
|
258
246
|
end
|
@@ -291,11 +279,15 @@ module RSMP
|
|
291
279
|
end
|
292
280
|
end
|
293
281
|
|
294
|
-
def store_last_sent_status
|
282
|
+
def store_last_sent_status message
|
283
|
+
component_id = message.attribute('cId')
|
295
284
|
@last_status_sent ||= {}
|
296
|
-
@last_status_sent[
|
297
|
-
|
298
|
-
|
285
|
+
@last_status_sent[component_id] ||= {}
|
286
|
+
message.attribute('sS').each do |item|
|
287
|
+
sCI, n, s = item['sCI'], item['n'], item['s']
|
288
|
+
@last_status_sent[component_id][sCI] ||= {}
|
289
|
+
@last_status_sent[component_id][sCI][n] = s
|
290
|
+
end
|
299
291
|
end
|
300
292
|
|
301
293
|
def status_update_timer now
|
@@ -316,7 +308,6 @@ module RSMP
|
|
316
308
|
last_sent = fetch_last_sent_status component, code, name
|
317
309
|
if current != last_sent
|
318
310
|
should_send = true
|
319
|
-
store_last_sent_status component, code, name, current
|
320
311
|
end
|
321
312
|
else
|
322
313
|
# send at regular intervals
|
@@ -360,6 +351,7 @@ module RSMP
|
|
360
351
|
"sS"=>sS
|
361
352
|
})
|
362
353
|
send_message update
|
354
|
+
store_last_sent_status update
|
363
355
|
end
|
364
356
|
end
|
365
357
|
|
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.
|
4
|
+
version: 0.5.2
|
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-11-
|
11
|
+
date: 2021-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|