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.
- checksums.yaml +4 -4
- data/bin/openc3cli +1 -1
- data/data/config/_id_items.yaml +2 -3
- data/data/config/telemetry_modifiers.yaml +0 -1
- data/lib/openc3/accessors/accessor.rb +3 -3
- data/lib/openc3/accessors/http_accessor.rb +1 -1
- data/lib/openc3/api/cmd_api.rb +17 -6
- data/lib/openc3/api/tlm_api.rb +16 -5
- data/lib/openc3/logs/buffered_packet_log_writer.rb +5 -0
- data/lib/openc3/microservices/interface_microservice.rb +29 -18
- data/lib/openc3/models/cvt_model.rb +9 -4
- data/lib/openc3/models/gem_model.rb +7 -5
- data/lib/openc3/models/metric_model.rb +8 -0
- data/lib/openc3/models/model.rb +21 -6
- data/lib/openc3/models/plugin_model.rb +8 -2
- data/lib/openc3/models/python_package_model.rb +3 -0
- data/lib/openc3/models/scope_model.rb +2 -2
- data/lib/openc3/models/target_model.rb +21 -28
- data/lib/openc3/models/tool_model.rb +2 -2
- data/lib/openc3/packets/json_packet.rb +5 -3
- data/lib/openc3/script/suite_results.rb +9 -9
- data/lib/openc3/topics/command_decom_topic.rb +2 -1
- data/lib/openc3/topics/command_topic.rb +2 -1
- data/lib/openc3/topics/telemetry_topic.rb +7 -2
- data/lib/openc3/utilities/aws_bucket.rb +21 -15
- data/lib/openc3/utilities/bucket.rb +1 -1
- data/lib/openc3/utilities/logger.rb +3 -3
- data/lib/openc3/utilities/process_manager.rb +15 -9
- data/lib/openc3/utilities/store_autoload.rb +29 -2
- data/lib/openc3/utilities/store_queued.rb +23 -24
- data/lib/openc3/version.rb +6 -6
- data/templates/tool_angular/package.json +2 -2
- data/templates/tool_svelte/package.json +1 -1
- data/templates/tool_vue/package.json +2 -2
- data/templates/widget/package.json +2 -2
- metadata +16 -7
- data/templates/tool_angular/yarn.lock +0 -8155
- data/templates/tool_react/yarn.lock +0 -7201
- data/templates/tool_svelte/yarn.lock +0 -5519
- data/templates/tool_vue/yarn.lock +0 -9455
- 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 { |
|
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 |
|
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 =>
|
228
|
+
rescue JSON::GeneratorError => e
|
236
229
|
Logger.error("Invalid text present in #{target_name} #{packet_name} #{type.to_s.downcase} packet")
|
237
|
-
raise
|
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(*
|
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 =>
|
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 #{
|
586
|
+
Logger.error("ERB error parsing #{key} due to #{e.message}")
|
594
587
|
else
|
595
|
-
raise "ERB error parsing #{key} due to #{
|
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 =>
|
671
|
-
Logger.error("Error undeploying target model #{@name} in scope #{@scope} due to #{
|
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 =>
|
706
|
-
raise "ERB error parsing: #{path}: #{
|
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 =>
|
759
|
+
rescue JSON::GeneratorError => e
|
767
760
|
Logger.error("Invalid text present in #{target_name} #{packet_name} tlm packet")
|
768
|
-
raise
|
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 =>
|
779
|
+
rescue JSON::GeneratorError => e
|
787
780
|
Logger.error("Invalid text present in #{target_name} #{packet_name} cmd packet")
|
788
|
-
raise
|
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 =>
|
791
|
+
rescue JSON::GeneratorError => e
|
799
792
|
Logger.error("Invalid text present in #{group} limits group")
|
800
|
-
raise
|
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,
|
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,
|
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,
|
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
|
-
|
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,
|
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,
|
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
|
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
|
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
|
47
|
+
# Executing a group
|
48
48
|
@context = "#{test_suite_class.name}:#{test_class.name} #{test_type}"
|
49
49
|
else
|
50
|
-
# Executing a
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
"
|
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
|
-
"
|
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
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
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/
|
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
|
-
|
209
|
+
EphemeralStoreQueued.write_topic("#{scope}__openc3_log_messages", data)
|
210
210
|
else
|
211
|
-
|
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 =>
|
72
|
-
Logger.error("ProcessManager unexpectedly died\n#{
|
73
|
-
raise "ProcessManager unexpectedly died\n#{
|
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"')
|
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
|
-
|
119
|
-
|
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.
|
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 |
|
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 =
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/openc3/version.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
OPENC3_VERSION = '5.
|
3
|
+
OPENC3_VERSION = '5.15.0'
|
4
4
|
module OpenC3
|
5
5
|
module Version
|
6
6
|
MAJOR = '5'
|
7
|
-
MINOR = '
|
8
|
-
PATCH = '
|
7
|
+
MINOR = '15'
|
8
|
+
PATCH = '0'
|
9
9
|
OTHER = ''
|
10
|
-
BUILD = '
|
10
|
+
BUILD = 'a7dd92ddb0ba4d378da1b611cafc5ad7e89a9223'
|
11
11
|
end
|
12
|
-
VERSION = '5.
|
13
|
-
GEM_VERSION = '5.
|
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.
|
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.
|
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
|
+
"@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.
|
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
|
+
"@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",
|