openc3 5.14.2 → 5.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +1 -1
  3. data/data/config/_id_items.yaml +2 -3
  4. data/data/config/telemetry_modifiers.yaml +0 -1
  5. data/lib/openc3/accessors/accessor.rb +3 -3
  6. data/lib/openc3/accessors/http_accessor.rb +1 -1
  7. data/lib/openc3/api/cmd_api.rb +17 -6
  8. data/lib/openc3/api/tlm_api.rb +16 -5
  9. data/lib/openc3/logs/buffered_packet_log_writer.rb +5 -0
  10. data/lib/openc3/microservices/interface_microservice.rb +29 -18
  11. data/lib/openc3/models/cvt_model.rb +9 -4
  12. data/lib/openc3/models/gem_model.rb +7 -5
  13. data/lib/openc3/models/metric_model.rb +8 -0
  14. data/lib/openc3/models/model.rb +21 -6
  15. data/lib/openc3/models/plugin_model.rb +8 -2
  16. data/lib/openc3/models/python_package_model.rb +3 -0
  17. data/lib/openc3/models/scope_model.rb +2 -2
  18. data/lib/openc3/models/target_model.rb +21 -28
  19. data/lib/openc3/models/tool_model.rb +2 -2
  20. data/lib/openc3/packets/json_packet.rb +5 -3
  21. data/lib/openc3/script/suite_results.rb +9 -9
  22. data/lib/openc3/topics/command_decom_topic.rb +2 -1
  23. data/lib/openc3/topics/command_topic.rb +2 -1
  24. data/lib/openc3/topics/telemetry_topic.rb +7 -2
  25. data/lib/openc3/utilities/aws_bucket.rb +21 -15
  26. data/lib/openc3/utilities/bucket.rb +1 -1
  27. data/lib/openc3/utilities/logger.rb +3 -3
  28. data/lib/openc3/utilities/process_manager.rb +15 -9
  29. data/lib/openc3/utilities/store_autoload.rb +29 -2
  30. data/lib/openc3/utilities/store_queued.rb +23 -24
  31. data/lib/openc3/version.rb +6 -6
  32. data/templates/tool_angular/package.json +2 -2
  33. data/templates/tool_svelte/package.json +1 -1
  34. data/templates/tool_vue/package.json +2 -2
  35. data/templates/widget/package.json +2 -2
  36. metadata +16 -7
  37. data/templates/tool_angular/yarn.lock +0 -8155
  38. data/templates/tool_react/yarn.lock +0 -7201
  39. data/templates/tool_svelte/yarn.lock +0 -5519
  40. data/templates/tool_vue/yarn.lock +0 -9455
  41. data/templates/widget/yarn.lock +0 -9338
@@ -97,7 +97,7 @@ module OpenC3
97
97
  # All targets with indication of modified targets
98
98
  def self.all_modified(scope:)
99
99
  targets = self.all(scope: scope)
100
- targets.each { |target_name, target| target['modified'] = false }
100
+ targets.each { |_target_name, target| target['modified'] = false }
101
101
 
102
102
  if ENV['OPENC3_LOCAL_MODE']
103
103
  modified_targets = OpenC3::LocalMode.modified_targets(scope: scope)
@@ -191,13 +191,6 @@ module OpenC3
191
191
  return result
192
192
  end
193
193
 
194
- # @return [Array] Array of all the packet names
195
- def self.packet_names(target_name, type: :TLM, scope:)
196
- raise "Unknown type #{type} for #{target_name}" unless VALID_TYPES.include?(type)
197
- # If the key doesn't exist or if there are no packets we return empty array
198
- Store.hkeys("#{scope}__openc3#{type.to_s.downcase}__#{target_name}").sort
199
- end
200
-
201
194
  # @return [Hash] Packet hash or raises an exception
202
195
  def self.packet(target_name, packet_name, type: :TLM, scope:)
203
196
  raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
@@ -216,7 +209,7 @@ module OpenC3
216
209
 
217
210
  result = []
218
211
  packets = Store.hgetall("#{scope}__openc3#{type.to_s.downcase}__#{target_name}")
219
- packets.sort.each do |packet_name, packet_json|
212
+ packets.sort.each do |_packet_name, packet_json|
220
213
  result << JSON.parse(packet_json, :allow_nan => true, :create_additions => true)
221
214
  end
222
215
  result
@@ -232,9 +225,9 @@ module OpenC3
232
225
 
233
226
  begin
234
227
  Store.hset("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
235
- rescue JSON::GeneratorError => err
228
+ rescue JSON::GeneratorError => e
236
229
  Logger.error("Invalid text present in #{target_name} #{packet_name} #{type.to_s.downcase} packet")
237
- raise err
230
+ raise e
238
231
  end
239
232
  end
240
233
 
@@ -403,7 +396,7 @@ module OpenC3
403
396
  @children = []
404
397
  end
405
398
 
406
- def as_json(*a)
399
+ def as_json(*_a)
407
400
  {
408
401
  'name' => @name,
409
402
  'folder_name' => @folder_name,
@@ -586,13 +579,13 @@ module OpenC3
586
579
  end
587
580
  end
588
581
  end
589
- rescue => error
582
+ rescue => e
590
583
  # ERB error parsing a screen is just a logger error because life can go on
591
584
  # With cmd/tlm or scripts this is a serious error and we raise
592
585
  if (filename.include?('/screens/'))
593
- Logger.error("ERB error parsing #{key} due to #{error.message}")
586
+ Logger.error("ERB error parsing #{key} due to #{e.message}")
594
587
  else
595
- raise "ERB error parsing #{key} due to #{error.message}"
588
+ raise "ERB error parsing #{key} due to #{e.message}"
596
589
  end
597
590
  end
598
591
  local_path = File.join(temp_dir, @name, target_folder_path)
@@ -667,8 +660,8 @@ module OpenC3
667
660
  @@item_map_cache[@name] = nil
668
661
 
669
662
  ConfigTopic.write({ kind: 'deleted', type: 'target', name: @name, plugin: @plugin }, scope: @scope)
670
- rescue Exception => error
671
- Logger.error("Error undeploying target model #{@name} in scope #{@scope} due to #{error}")
663
+ rescue Exception => e
664
+ Logger.error("Error undeploying target model #{@name} in scope #{@scope} due to #{e}")
672
665
  end
673
666
 
674
667
  ##################################################
@@ -702,8 +695,8 @@ module OpenC3
702
695
  return ERB.new(data.force_encoding("UTF-8").comment_erb(), trim_mode: "-").result(b)
703
696
  end
704
697
  end
705
- rescue => error
706
- raise "ERB error parsing: #{path}: #{error.formatted}"
698
+ rescue => e
699
+ raise "ERB error parsing: #{path}: #{e.formatted}"
707
700
  end
708
701
  end
709
702
 
@@ -763,9 +756,9 @@ module OpenC3
763
756
  Logger.info "Configuring tlm packet: #{target_name} #{packet_name}"
764
757
  begin
765
758
  Store.hset("#{@scope}__openc3tlm__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
766
- rescue JSON::GeneratorError => err
759
+ rescue JSON::GeneratorError => e
767
760
  Logger.error("Invalid text present in #{target_name} #{packet_name} tlm packet")
768
- raise err
761
+ raise e
769
762
  end
770
763
  json_hash = Hash.new
771
764
  packet.sorted_items.each do |item|
@@ -783,9 +776,9 @@ module OpenC3
783
776
  Logger.info "Configuring cmd packet: #{target_name} #{packet_name}"
784
777
  begin
785
778
  Store.hset("#{@scope}__openc3cmd__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
786
- rescue JSON::GeneratorError => err
779
+ rescue JSON::GeneratorError => e
787
780
  Logger.error("Invalid text present in #{target_name} #{packet_name} cmd packet")
788
- raise err
781
+ raise e
789
782
  end
790
783
  end
791
784
  end
@@ -795,9 +788,9 @@ module OpenC3
795
788
  system.limits.groups.each do |group, items|
796
789
  begin
797
790
  Store.hset("#{@scope}__limits_groups", group, JSON.generate(items))
798
- rescue JSON::GeneratorError => err
791
+ rescue JSON::GeneratorError => e
799
792
  Logger.error("Invalid text present in #{group} limits group")
800
- raise err
793
+ raise e
801
794
  end
802
795
  end
803
796
  end
@@ -1107,7 +1100,7 @@ module OpenC3
1107
1100
 
1108
1101
  # Figure out if there are individual packets assigned to this microservice
1109
1102
  target_microservices.sort! {|a, b| a.length <=> b.length}
1110
- target_microservices.each_with_index do |packet_names, index|
1103
+ target_microservices.each_with_index do |packet_names, _index|
1111
1104
  topics = []
1112
1105
  packet_names.each do |packet_name|
1113
1106
  topics << "#{topic_prefix}__#{packet_name}"
@@ -1146,7 +1139,7 @@ module OpenC3
1146
1139
  packet_topic_list = []
1147
1140
  decom_topic_list = []
1148
1141
  begin
1149
- system.commands.packets(@name).each do |packet_name, packet|
1142
+ system.commands.packets(@name).each do |packet_name, _packet|
1150
1143
  command_topic_list << "#{@scope}__COMMAND__{#{@name}}__#{packet_name}"
1151
1144
  decom_command_topic_list << "#{@scope}__DECOMCMD__{#{@name}}__#{packet_name}"
1152
1145
  end
@@ -1154,7 +1147,7 @@ module OpenC3
1154
1147
  # No command packets for this target
1155
1148
  end
1156
1149
  begin
1157
- system.telemetry.packets(@name).each do |packet_name, packet|
1150
+ system.telemetry.packets(@name).each do |packet_name, _packet|
1158
1151
  packet_topic_list << "#{@scope}__TELEMETRY__{#{@name}}__#{packet_name}"
1159
1152
  decom_topic_list << "#{@scope}__DECOM__{#{@name}}__#{packet_name}"
1160
1153
  end
@@ -157,7 +157,7 @@ module OpenC3
157
157
  @disable_erb = disable_erb
158
158
  end
159
159
 
160
- def create(update: false, force: false)
160
+ def create(update: false, force: false, queued: false)
161
161
  tools = self.class.all(scope: @scope)
162
162
 
163
163
  # Make sure a tool with this folder_name doesn't already exist
@@ -181,7 +181,7 @@ module OpenC3
181
181
  end
182
182
  end
183
183
 
184
- super(update: update, force: force)
184
+ super(update: update, force: force, queued: queued)
185
185
  end
186
186
 
187
187
  def as_json(*a)
@@ -67,7 +67,9 @@ module OpenC3
67
67
  def read(name, value_type = :CONVERTED, reduced_type = nil)
68
68
  value = nil
69
69
  array_index = nil
70
- if name[-1] == ']'
70
+ # Check for array index to handle array items but also make sure there
71
+ # isn't a REAL item that has brackets in the name
72
+ if name[-1] == ']' and !@json_hash.include?(name)
71
73
  open_bracket_index = name.index('[')
72
74
  if open_bracket_index
73
75
  array_index = name[(open_bracket_index + 1)..-2].to_i
@@ -212,12 +214,12 @@ module OpenC3
212
214
  else
213
215
  postfix = nil if value_type == :RAW
214
216
  end
215
- @json_hash.each do |key, value|
217
+ @json_hash.each do |key, _value|
216
218
  key_split = key.split("__")
217
219
  result[key_split[0]] = true if key_split[1] == postfix
218
220
  end
219
221
  else
220
- @json_hash.each { |key, value| result[key.split("__")[0]] = true }
222
+ @json_hash.each { |key, _value| result[key.split("__")[0]] = true }
221
223
  end
222
224
  return result.keys
223
225
  end
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2024, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -22,7 +22,7 @@
22
22
 
23
23
  module OpenC3
24
24
  class SuiteResults
25
- attr_accessor :metadata
25
+ attr_accessor :metadata, :context
26
26
 
27
27
  def initialize
28
28
  @report = nil
@@ -41,13 +41,13 @@ module OpenC3
41
41
  @report = []
42
42
 
43
43
  if test_case
44
- # Executing a single test case
44
+ # Executing a script
45
45
  @context = "#{test_suite_class.name}:#{test_class.name}:#{test_case} #{test_type}"
46
46
  elsif test_class
47
- # Executing an entire test
47
+ # Executing a group
48
48
  @context = "#{test_suite_class.name}:#{test_class.name} #{test_type}"
49
49
  else
50
- # Executing a test suite
50
+ # Executing a suite
51
51
  @context = "#{test_suite_class.name} #{test_type}"
52
52
  end
53
53
 
@@ -75,7 +75,7 @@ module OpenC3
75
75
  line.chomp!
76
76
  line = line.inspect.remove_quotes
77
77
  end
78
- @report << ' ' + line.strip
78
+ @report << (' ' + line.strip)
79
79
  end
80
80
  end
81
81
  if result.exceptions
@@ -90,7 +90,7 @@ module OpenC3
90
90
  line.chomp!
91
91
  line = line.inspect.remove_quotes
92
92
  end
93
- @report << ' ' + line.strip
93
+ @report << (' ' + line.strip)
94
94
  end
95
95
  @report << '' if index != (result.exceptions.length - 1)
96
96
  end
@@ -172,11 +172,11 @@ module OpenC3
172
172
  end
173
173
 
174
174
  def write(string)
175
- @report << Time.now.sys.formatted + ': ' + string
175
+ @report << (Time.now.sys.formatted + ': ' + string)
176
176
  end
177
177
 
178
178
  def puts(string)
179
- @report << Time.now.sys.formatted + ': ' + string
179
+ @report << (Time.now.sys.formatted + ': ' + string)
180
180
  end
181
181
 
182
182
  # def collect_metadata(parent = nil)
@@ -21,6 +21,7 @@
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/topics/topic'
24
+ require 'openc3/utilities/store_queued'
24
25
 
25
26
  module OpenC3
26
27
  class CommandDecomTopic < Topic
@@ -39,7 +40,7 @@ module OpenC3
39
40
  json_hash[item.name + "__U"] = packet.read_item(item, :WITH_UNITS) if item.units
40
41
  end
41
42
  msg_hash['json_data'] = JSON.generate(json_hash.as_json(:allow_nan => true))
42
- Topic.write_topic(topic, msg_hash)
43
+ EphemeralStoreQueued.write_topic(topic, msg_hash)
43
44
  end
44
45
 
45
46
  def self.get_cmd_item(target_name, packet_name, param_name, type: :WITH_UNITS, scope: $openc3_scope)
@@ -21,6 +21,7 @@
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/topics/topic'
24
+ require 'openc3/utilities/store_queued'
24
25
  require 'openc3/utilities/open_telemetry'
25
26
 
26
27
  module OpenC3
@@ -36,7 +37,7 @@ module OpenC3
36
37
  received_count: packet.received_count,
37
38
  stored: packet.stored.to_s,
38
39
  buffer: packet.buffer(false) }
39
- Topic.write_topic(topic, msg_hash)
40
+ EphemeralStoreQueued.write_topic(topic, msg_hash)
40
41
  end
41
42
 
42
43
  # @param command [Hash] Command hash structure read to be written to a topic
@@ -21,10 +21,11 @@
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/topics/topic'
24
+ require 'openc3/utilities/store_queued'
24
25
 
25
26
  module OpenC3
26
27
  class TelemetryTopic < Topic
27
- def self.write_packet(packet, scope:)
28
+ def self.write_packet(packet, queued: false, scope:)
28
29
  msg_hash = {
29
30
  :time => packet.packet_time.to_nsec_from_epoch,
30
31
  :received_time => packet.received_time.to_nsec_from_epoch,
@@ -35,7 +36,11 @@ module OpenC3
35
36
  :buffer => packet.buffer(false)
36
37
  }
37
38
  msg_hash[:extra] = JSON.generate(packet.extra.as_json, allow_nan: true) if packet.extra
38
- Topic.write_topic("#{scope}__TELEMETRY__{#{packet.target_name}}__#{packet.packet_name}", msg_hash)
39
+ if queued
40
+ EphemeralStoreQueued.write_topic("#{scope}__TELEMETRY__{#{packet.target_name}}__#{packet.packet_name}", msg_hash)
41
+ else
42
+ Topic.write_topic("#{scope}__TELEMETRY__{#{packet.target_name}}__#{packet.packet_name}", msg_hash)
43
+ end
39
44
  end
40
45
  end
41
46
  end
@@ -26,7 +26,9 @@ module OpenC3
26
26
  CREATE_CHECK_COUNT = 100 # 10 seconds
27
27
 
28
28
  def initialize
29
+ super()
29
30
  @client = Aws::S3::Client.new
31
+ @aws_arn = ENV['OPENC3_AWS_ARN_PREFIX'] || 'arn:aws'
30
32
  end
31
33
 
32
34
  def create(bucket)
@@ -59,7 +61,7 @@ module OpenC3
59
61
  ]
60
62
  },
61
63
  "Resource": [
62
- "arn:aws:s3:::#{bucket}"
64
+ "#{@aws_arn}:s3:::#{bucket}"
63
65
  ],
64
66
  "Sid": ""
65
67
  },
@@ -74,7 +76,7 @@ module OpenC3
74
76
  ]
75
77
  },
76
78
  "Resource": [
77
- "arn:aws:s3:::#{bucket}/*"
79
+ "#{@aws_arn}:s3:::#{bucket}/*"
78
80
  ],
79
81
  "Sid": ""
80
82
  }
@@ -198,19 +200,23 @@ module OpenC3
198
200
  end
199
201
 
200
202
  # @returns [Boolean] Whether the file exists
201
- def check_object(bucket:, key:)
202
- @client.wait_until(:object_exists,
203
- {
204
- bucket: bucket,
205
- key: key
206
- },
207
- {
208
- max_attempts: 30,
209
- delay: 0.1, # seconds
210
- }
211
- )
212
- true
213
- rescue Aws::Waiters::Errors::TooManyAttemptsError
203
+ def check_object(bucket:, key:, retries: true)
204
+ if retries
205
+ @client.wait_until(:object_exists,
206
+ {
207
+ bucket: bucket,
208
+ key: key
209
+ },
210
+ {
211
+ max_attempts: 30,
212
+ delay: 0.1, # seconds
213
+ }
214
+ )
215
+ true
216
+ else
217
+ head_object(bucket: bucket, key: key)
218
+ end
219
+ rescue NotFound, Aws::Waiters::Errors::TooManyAttemptsError
214
220
  false
215
221
  end
216
222
 
@@ -69,7 +69,7 @@ module OpenC3
69
69
  raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
70
70
  end
71
71
 
72
- def check_object(bucket:, key:)
72
+ def check_object(bucket:, key:, retries: true)
73
73
  raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
74
74
  end
75
75
 
@@ -22,7 +22,7 @@
22
22
 
23
23
  require 'openc3/core_ext/class'
24
24
  require 'openc3/core_ext/time'
25
- require 'openc3/topics/topic'
25
+ require 'openc3/utilities/store_queued'
26
26
  require 'socket'
27
27
  require 'logger'
28
28
  require 'time'
@@ -206,9 +206,9 @@ module OpenC3
206
206
  end
207
207
  unless @no_store
208
208
  if scope
209
- Topic.write_topic("#{scope}__openc3_log_messages", data)
209
+ EphemeralStoreQueued.write_topic("#{scope}__openc3_log_messages", data)
210
210
  else
211
- Topic.write_topic("NOSCOPE__openc3_log_messages", data)
211
+ EphemeralStoreQueued.write_topic("NOSCOPE__openc3_log_messages", data)
212
212
  end
213
213
  end
214
214
  end
@@ -68,9 +68,9 @@ module OpenC3
68
68
  @monitor_thread = Thread.new do
69
69
  begin
70
70
  monitor()
71
- rescue => err
72
- Logger.error("ProcessManager unexpectedly died\n#{err.formatted}", scope: 'DEFAULT')
73
- raise "ProcessManager unexpectedly died\n#{err.formatted}"
71
+ rescue => e
72
+ Logger.error("ProcessManager unexpectedly died\n#{e.formatted}", scope: 'DEFAULT')
73
+ raise "ProcessManager unexpectedly died\n#{e.formatted}"
74
74
  end
75
75
  end
76
76
  end
@@ -96,7 +96,9 @@ module OpenC3
96
96
  process.status.output = output
97
97
  if process.exit_code != 0
98
98
  process.status.state = "Crashed"
99
- elsif output.include?('"level":"ERROR"') || output.include?('"level":"WARN"')
99
+ elsif output.include?('"level":"ERROR"')
100
+ process.status.state = "Error"
101
+ elsif output.include?('"level":"WARN"')
100
102
  process.status.state = "Warning"
101
103
  else
102
104
  process.status.state = "Complete"
@@ -115,11 +117,15 @@ module OpenC3
115
117
  process.status.update
116
118
  end
117
119
  processes_to_delete.each do |process|
118
- if process.status.state == "Complete"
119
- Logger.info("Process #{process.status.name}:#{process.process_type}:#{process.detail} completed with state #{process.status.state}", scope: process.scope)
120
+ message = "Process #{process.status.name}:#{process.process_type}:#{process.detail} completed with state #{process.status.state}\nProcess Output:\n#{process.status.output}"
121
+ if process.status.state != "Complete"
122
+ if process.status.state == "Warning"
123
+ Logger.warn(message, scope: process.scope)
124
+ else
125
+ Logger.error(message, scope: process.scope)
126
+ end
120
127
  else
121
- Logger.error("Process #{process.status.name}:#{process.process_type}:#{process.detail} completed with state #{process.status.state}", scope: process.scope)
122
- Logger.error("Process Output:\n#{process.status.output}", scope: process.scope)
128
+ Logger.info(message, scope: process.scope)
123
129
  end
124
130
 
125
131
  @processes.delete(process)
@@ -131,7 +137,7 @@ module OpenC3
131
137
  scopes = ScopeModel.names
132
138
  scopes.each do |scope|
133
139
  statuses = ProcessStatusModel.get_all_models(scope: scope)
134
- statuses.each do |status_name, status|
140
+ statuses.each do |_status_name, status|
135
141
  if (current_time - Time.from_nsec_from_epoch(status.updated_at)) > CLEANUP_CYCLE_SECONDS
136
142
  status.destroy
137
143
  end
@@ -21,6 +21,7 @@
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'redis'
24
+ require "hiredis-client"
24
25
  require 'json'
25
26
  require 'connection_pool'
26
27
 
@@ -32,6 +33,32 @@ else
32
33
  end
33
34
 
34
35
  module OpenC3
36
+ class StoreConnectionPool < ConnectionPool
37
+ NO_OPTIONS = {}
38
+
39
+ def pipelined
40
+ with(NO_OPTIONS) do |redis|
41
+ redis.pipelined do |pipeline|
42
+ Thread.current[:pipeline] = pipeline
43
+ begin
44
+ yield
45
+ ensure
46
+ Thread.current[:pipeline] = nil
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def with(options = NO_OPTIONS, &block)
53
+ pipeline = Thread.current[:pipeline]
54
+ if pipeline
55
+ yield pipeline
56
+ else
57
+ super(options, &block)
58
+ end
59
+ end
60
+ end
61
+
35
62
  class Store
36
63
  # Variable that holds the singleton instance
37
64
  @instance = nil
@@ -67,7 +94,7 @@ module OpenC3
67
94
  @redis_username = ENV['OPENC3_REDIS_USERNAME']
68
95
  @redis_key = ENV['OPENC3_REDIS_PASSWORD']
69
96
  @redis_url = "redis://#{ENV['OPENC3_REDIS_HOSTNAME']}:#{ENV['OPENC3_REDIS_PORT']}"
70
- @redis_pool = ConnectionPool.new(size: pool_size) { build_redis() }
97
+ @redis_pool = StoreConnectionPool.new(size: pool_size) { build_redis() }
71
98
  end
72
99
 
73
100
  unless $openc3_redis_cluster
@@ -212,7 +239,7 @@ module OpenC3
212
239
  def initialize(pool_size = 10)
213
240
  super(pool_size)
214
241
  @redis_url = "redis://#{ENV['OPENC3_REDIS_EPHEMERAL_HOSTNAME']}:#{ENV['OPENC3_REDIS_EPHEMERAL_PORT']}"
215
- @redis_pool = ConnectionPool.new(size: pool_size) { build_redis() }
242
+ @redis_pool = StoreConnectionPool.new(size: pool_size) { build_redis() }
216
243
  end
217
244
  end
218
245
  end
@@ -60,19 +60,29 @@ module OpenC3
60
60
  end
61
61
  end
62
62
 
63
+ def set_update_interval(interval)
64
+ if interval < @update_interval and interval > 0.0
65
+ @update_interval = interval
66
+ end
67
+ end
68
+
69
+ def process_queue
70
+ unless @store_queue.empty?
71
+ # Pipeline the requests to redis to improve performance
72
+ @store.redis_pool.pipelined do
73
+ while !@store_queue.empty?
74
+ action = @store_queue.pop()
75
+ @store.public_send(action.message, *action.args, **action.kwargs, &action.block)
76
+ end
77
+ end
78
+ end
79
+ end
80
+
63
81
  def store_thread_body
64
82
  while true
65
83
  start_time = Time.now
66
84
 
67
- unless @store_queue.empty?
68
- # Pipeline the requests to redis to improve performance
69
- @store.pipelined do
70
- while !@store_queue.empty?
71
- action = @store_queue.pop()
72
- @store.method_missing(action.message, *action.args, **action.kwargs, &action.block)
73
- end
74
- end
75
- end
85
+ process_queue()
76
86
 
77
87
  # Only check whether to update at a set interval
78
88
  run_time = Time.now - start_time
@@ -87,25 +97,14 @@ module OpenC3
87
97
  OpenC3.kill_thread(self, @update_thread) if @update_thread
88
98
  @update_thread = nil
89
99
  # Drain the queue before shutdown
90
- unless @store_queue.empty?
91
- # Pipeline the requests to redis to improve performance
92
- @store.pipelined do
93
- while !@store_queue.empty?
94
- action = @store_queue.pop()
95
- @store.method_missing(action.message, *action.args, **action.kwargs, &action.block)
96
- end
97
- end
98
- end
100
+ process_queue()
99
101
  end
100
102
 
103
+ MessageStruct = Struct.new(:message, :args, :kwargs, :block)
104
+
101
105
  # Record the message for pipelining by the thread
102
106
  def method_missing(message, *args, **kwargs, &block)
103
- o = OpenStruct.new
104
- o.message = message
105
- o.args = args
106
- o.kwargs = kwargs
107
- o.block = block
108
- @store_queue.push(o)
107
+ @store_queue.push(MessageStruct.new(message, args, kwargs, block))
109
108
  end
110
109
 
111
110
  # Returns the store we're working with
@@ -1,14 +1,14 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- OPENC3_VERSION = '5.14.2'
3
+ OPENC3_VERSION = '5.15.0'
4
4
  module OpenC3
5
5
  module Version
6
6
  MAJOR = '5'
7
- MINOR = '14'
8
- PATCH = '2'
7
+ MINOR = '15'
8
+ PATCH = '0'
9
9
  OTHER = ''
10
- BUILD = 'e5d9da06d95d4404fba6f9fd5a74a130ef176bd4'
10
+ BUILD = 'a7dd92ddb0ba4d378da1b611cafc5ad7e89a9223'
11
11
  end
12
- VERSION = '5.14.2'
13
- GEM_VERSION = '5.14.2'
12
+ VERSION = '5.15.0'
13
+ GEM_VERSION = '5.15.0'
14
14
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "5.14.2",
3
+ "version": "5.15.0",
4
4
  "scripts": {
5
5
  "ng": "ng",
6
6
  "start": "ng serve",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "private": true,
14
14
  "dependencies": {
15
- "@openc3/tool-common": "5.14.2",
15
+ "@openc3/tool-common": "5.15.0",
16
16
  "@angular/animations": "^17.0.8",
17
17
  "@angular/cdk": "^17.0.4",
18
18
  "@angular/common": "^17.0.8",
@@ -11,7 +11,7 @@
11
11
  "smui-theme": "smui-theme compile build/smui.css -i src/theme"
12
12
  },
13
13
  "dependencies": {
14
- "@openc3/tool-common": "5.14.2",
14
+ "@openc3/tool-common": "5.15.0",
15
15
  "@astrouxds/astro-web-components": "7.20.0",
16
16
  "@smui/button": "^7.0.0-beta.16",
17
17
  "@smui/card": "^7.0.0-beta.16",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "5.14.2",
3
+ "version": "5.15.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -11,7 +11,7 @@
11
11
  "test:components": "vue-cli-service test:components"
12
12
  },
13
13
  "dependencies": {
14
- "@openc3/tool-common": "5.14.2",
14
+ "@openc3/tool-common": "5.15.0",
15
15
  "@astrouxds/astro-web-components": "7.20.0",
16
16
  "axios": "1.6.5",
17
17
  "date-fns": "2.30.0",