openc3 5.14.2 → 5.15.0

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.

Potentially problematic release.


This version of openc3 might be problematic. Click here for more details.

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",