rsmp 0.4.6 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c975252bdf622f3e6bd545e2eca8f4fcf2c9c5a5f04acf159cd162882bf4f491
4
- data.tar.gz: ec26cc377c14611389a8f0c9b82cf2137a76523cca3ce445513bc7e2ea5466d6
3
+ metadata.gz: 7290ac834b3609265b8e74ecc1d03a10c08b7e0f81411516ffa7dca1c3101bfb
4
+ data.tar.gz: 8a81e821c60fd148da62222724cd038eb85a69251e0e52603403edcb5a1256bf
5
5
  SHA512:
6
- metadata.gz: 243e70433cafb8573fc9e4ffcd6a55ece6d369df6201041e6481f88810ffdf907830197854330a28c91cfc2075b767cf379590bd7f80214189a94d4a0b3c03e9
7
- data.tar.gz: ac86a77b8685491c0f08fb14bd4e15552eabf73d177b7f5415b809628bab2684a71e4df3aad451fc2822c808b44d036d4c4910998b369cb373f0a4b8b2294ece
6
+ metadata.gz: f2989f8d80113ebfdbde28c669d5255787b353949e3dc75c704ccfae54f2e579424426b1fa1144a616f087238c0f76350bdf009665b25514eacc115ed1ef1247
7
+ data.tar.gz: fc674e02fed369f00c56c3152494dee25d7da66733971345550c8846df191b732d6cc3a60df7502ab7168b7ad2b66ba01d4195eb654e2d45c04b987ea932b9be
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.4.6)
4
+ rsmp (0.5.0)
5
5
  async (~> 1.29.1)
6
6
  async-io (~> 1.32.1)
7
7
  colorize (~> 0.8.1)
@@ -19,6 +19,7 @@ log:
19
19
  text: true
20
20
  direction: true
21
21
  level: false
22
+ debug: true
22
23
  json: true
23
24
  acknowledgements: false
24
25
  watchdogs: false
data/config/tlc.yaml CHANGED
@@ -38,6 +38,7 @@ log:
38
38
  ip: false
39
39
  site_id: true
40
40
  level: false
41
+ debug: true
41
42
  text: true
42
43
  direction: true
43
44
  json: true
@@ -7,7 +7,12 @@ module RSMP
7
7
 
8
8
  def initialize proxy, options={}
9
9
  super proxy, options
10
- @options = options.clone
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: #{message.attribute('rea')}")
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
@@ -12,6 +12,9 @@ module RSMP
12
12
  def notify message
13
13
  end
14
14
 
15
+ def notify_error error, options={}
16
+ end
17
+
15
18
  def listen &block
16
19
  @proxy.add_listener self
17
20
  yield
@@ -102,6 +102,5 @@ module RSMP
102
102
  end
103
103
  @proxy.log "#{@title.capitalize} collect reached #{summary}", level: :debug
104
104
  end
105
-
106
105
  end
107
106
  end
@@ -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/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
 
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
@@ -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
- notify message
323
- expect_version_message(message) unless @version_determined
324
- process_message message
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 FatalError.new "RSMP versions [#{message.versions.join(',')}] requested, but only [#{versions.join(',')}] supported."
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 FatalError.new "Version must be received first"
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: #{message.attribute('rea')}"
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
@@ -75,10 +75,6 @@ module RSMP
75
75
  acknowledge message
76
76
  end
77
77
 
78
- def process_deferred
79
- supervisor.process_deferred
80
- end
81
-
82
78
  def version_accepted message
83
79
  log "Received Version message for site #{@site_id}", message: message, level: :log
84
80
  start_timer
@@ -333,6 +329,7 @@ module RSMP
333
329
 
334
330
  def notify_error e, options={}
335
331
  @supervisor.notify_error e, options if @supervisor
332
+ distribute_error e, options
336
333
  end
337
334
 
338
335
  def collect_alarms parent_task, options={}
@@ -246,7 +246,7 @@ module RSMP
246
246
 
247
247
  def check_site_already_connected site_id
248
248
  site = find_site(site_id)
249
- raise FatalError.new "Site '#{site_id}' already connected" if site != nil && site != self
249
+ raise HandshakeError.new "Site '#{site_id}' already connected" if site != nil && site != self
250
250
  end
251
251
 
252
252
  def site_id_to_site_setting site_id
@@ -256,7 +256,7 @@ module RSMP
256
256
  return settings
257
257
  end
258
258
  end
259
- raise FatalError.new "site id #{site_id} unknown"
259
+ raise HandshakeError.new "site id #{site_id} unknown"
260
260
  end
261
261
 
262
262
  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
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.4.6"
2
+ VERSION = "0.5.0"
3
3
  end
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.6
4
+ version: 0.5.0
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-01 00:00:00.000000000 Z
11
+ date: 2021-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -258,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
258
  - !ruby/object:Gem::Version
259
259
  version: '0'
260
260
  requirements: []
261
- rubygems_version: 3.2.26
261
+ rubygems_version: 3.2.15
262
262
  signing_key:
263
263
  specification_version: 4
264
264
  summary: RoadSide Message Protocol (RSMP) library.