openc3 5.14.2 → 5.15.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 +50 -7
- data/lib/openc3/api/tlm_api.rb +16 -5
- data/lib/openc3/logs/buffered_packet_log_writer.rb +5 -0
- data/lib/openc3/logs/packet_log_reader.rb +8 -9
- data/lib/openc3/microservices/interface_microservice.rb +29 -18
- data/lib/openc3/microservices/trigger_group_microservice.rb +9 -9
- data/lib/openc3/models/auth_model.rb +5 -7
- 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/commands.rb +2 -2
- data/lib/openc3/script/storage.rb +28 -12
- data/lib/openc3/script/suite_results.rb +9 -9
- data/lib/openc3/system/system.rb +4 -5
- data/lib/openc3/top_level.rb +32 -23
- 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/authorization.rb +1 -1
- 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 +33 -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
data/lib/openc3/top_level.rb
CHANGED
@@ -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,6 @@
|
|
22
22
|
|
23
23
|
# This file contains top level functions in the OpenC3 namespace
|
24
24
|
|
25
|
-
require 'thread'
|
26
25
|
require 'digest'
|
27
26
|
require 'open3'
|
28
27
|
require 'openc3/core_ext'
|
@@ -50,6 +49,16 @@ class HazardousError < StandardError
|
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
52
|
+
# If a disabled command is sent through the {OpenC3::Api} this error is raised.
|
53
|
+
class DisabledError < StandardError
|
54
|
+
attr_accessor :target_name
|
55
|
+
attr_accessor :cmd_name
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
"#{target_name} #{cmd_name} is Disabled"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
53
62
|
# OpenC3 is almost
|
54
63
|
# wholly contained within the OpenC3 module. OpenC3 also extends some of the
|
55
64
|
# core Ruby classes to add additional functionality.
|
@@ -102,18 +111,18 @@ module OpenC3
|
|
102
111
|
file.write(OPENC3_MARSHAL_HEADER)
|
103
112
|
file.write(Marshal.dump(obj))
|
104
113
|
end
|
105
|
-
rescue Exception =>
|
114
|
+
rescue Exception => e
|
106
115
|
begin
|
107
116
|
File.delete(marshal_filename)
|
108
117
|
rescue Exception
|
109
118
|
# Oh well - we tried
|
110
119
|
end
|
111
|
-
if
|
112
|
-
original_backtrace =
|
113
|
-
|
114
|
-
|
120
|
+
if e.class == TypeError and e.message =~ /Thread::Mutex/
|
121
|
+
original_backtrace = e.backtrace
|
122
|
+
e = e.exception("Mutex exists in a packet. Note: Packets must not be read during class initializers for Conversions, Limits Responses, etc.: #{e}")
|
123
|
+
e.set_backtrace(original_backtrace)
|
115
124
|
end
|
116
|
-
self.handle_fatal_exception(
|
125
|
+
self.handle_fatal_exception(e)
|
117
126
|
end
|
118
127
|
|
119
128
|
# Loads the marshal file back into a Ruby object
|
@@ -132,9 +141,9 @@ module OpenC3
|
|
132
141
|
Logger.warn "Marshal load failed with invalid marshal file: #{marshal_filename}"
|
133
142
|
return nil
|
134
143
|
end
|
135
|
-
rescue Exception =>
|
144
|
+
rescue Exception => e
|
136
145
|
if File.exist?(marshal_filename)
|
137
|
-
Logger.error "Marshal load failed with exception: #{marshal_filename}\n#{
|
146
|
+
Logger.error "Marshal load failed with exception: #{marshal_filename}\n#{e.formatted}"
|
138
147
|
else
|
139
148
|
Logger.info "Marshal file does not exist: #{marshal_filename}"
|
140
149
|
end
|
@@ -145,7 +154,7 @@ module OpenC3
|
|
145
154
|
rescue Exception
|
146
155
|
# Oh well - we tried
|
147
156
|
end
|
148
|
-
self.handle_fatal_exception(
|
157
|
+
self.handle_fatal_exception(e) if File.exist?(marshal_filename)
|
149
158
|
return nil
|
150
159
|
end
|
151
160
|
|
@@ -354,7 +363,7 @@ module OpenC3
|
|
354
363
|
#
|
355
364
|
# @param error [Exception] The exception to handle
|
356
365
|
# @param try_gui [Boolean] Whether to try and create a GUI exception popup
|
357
|
-
def self.handle_fatal_exception(error,
|
366
|
+
def self.handle_fatal_exception(error, _try_gui = true)
|
358
367
|
unless SystemExit === error or SignalException === error
|
359
368
|
$openc3_fatal_exception = error
|
360
369
|
self.write_exception_file(error)
|
@@ -380,7 +389,7 @@ module OpenC3
|
|
380
389
|
#
|
381
390
|
# @param error [Exception] The exception to handle
|
382
391
|
# @param try_gui [Boolean] Whether to try and create a GUI exception popup
|
383
|
-
def self.handle_critical_exception(error,
|
392
|
+
def self.handle_critical_exception(error, _try_gui = true)
|
384
393
|
Logger.error "Critical Exception! #{error.formatted}"
|
385
394
|
self.write_exception_file(error)
|
386
395
|
end
|
@@ -397,15 +406,15 @@ module OpenC3
|
|
397
406
|
retry_count = 0
|
398
407
|
begin
|
399
408
|
yield
|
400
|
-
rescue =>
|
409
|
+
rescue => e
|
401
410
|
Logger.error "#{name} thread unexpectedly died. Retries: #{retry_count} of #{retry_attempts}"
|
402
|
-
Logger.error
|
411
|
+
Logger.error e.formatted
|
403
412
|
retry_count += 1
|
404
413
|
if retry_count <= retry_attempts
|
405
|
-
self.write_exception_file(
|
414
|
+
self.write_exception_file(e)
|
406
415
|
retry
|
407
416
|
end
|
408
|
-
handle_fatal_exception(
|
417
|
+
handle_fatal_exception(e)
|
409
418
|
end
|
410
419
|
end
|
411
420
|
end
|
@@ -440,15 +449,15 @@ module OpenC3
|
|
440
449
|
# @param log_error [Boolean] Whether to log an error if we can't require the class
|
441
450
|
def self.require_file(filename, log_error = true)
|
442
451
|
require filename
|
443
|
-
rescue Exception =>
|
444
|
-
msg = "Unable to require #{filename} due to #{
|
452
|
+
rescue Exception => e
|
453
|
+
msg = "Unable to require #{filename} due to #{e.message}. "\
|
445
454
|
"Ensure #{filename} is in the OpenC3 lib directory."
|
446
455
|
Logger.error msg if log_error
|
447
456
|
raise $!, msg, $!.backtrace
|
448
457
|
end
|
449
458
|
|
450
459
|
# @param filename [String] Name of the file to open in the web browser
|
451
|
-
def self.open_in_web_browser(
|
460
|
+
def self.open_in_web_browser(_filename)
|
452
461
|
puts "open_in_web_browser is DEPRECATED"
|
453
462
|
end
|
454
463
|
|
@@ -456,12 +465,12 @@ module OpenC3
|
|
456
465
|
# Working directory is global, so this can make other threads wait
|
457
466
|
# Ruby Dir.chdir with block always throws an error if multiple threads
|
458
467
|
# call Dir.chdir
|
459
|
-
def self.set_working_dir(working_dir, &
|
468
|
+
def self.set_working_dir(working_dir, &)
|
460
469
|
if $openc3_chdir_mutex.owned?
|
461
|
-
set_working_dir_internal(working_dir, &
|
470
|
+
set_working_dir_internal(working_dir, &)
|
462
471
|
else
|
463
472
|
$openc3_chdir_mutex.synchronize do
|
464
|
-
set_working_dir_internal(working_dir, &
|
473
|
+
set_working_dir_internal(working_dir, &)
|
465
474
|
end
|
466
475
|
end
|
467
476
|
end
|
@@ -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
|
@@ -42,7 +42,7 @@ rescue LoadError
|
|
42
42
|
|
43
43
|
if $openc3_authorize
|
44
44
|
raise AuthError.new("Token is required") unless token
|
45
|
-
unless OpenC3::AuthModel.verify(token
|
45
|
+
unless OpenC3::AuthModel.verify(token)
|
46
46
|
raise AuthError.new("Password is invalid for '#{permission}' permission")
|
47
47
|
end
|
48
48
|
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,36 @@ else
|
|
32
33
|
end
|
33
34
|
|
34
35
|
module OpenC3
|
36
|
+
class StoreConnectionPool < ConnectionPool
|
37
|
+
NO_OPTIONS = {}
|
38
|
+
|
39
|
+
def pipelined
|
40
|
+
if $openc3_redis_cluster
|
41
|
+
yield # TODO: Update keys to support pipelining in cluster
|
42
|
+
else
|
43
|
+
with(NO_OPTIONS) do |redis|
|
44
|
+
redis.pipelined do |pipeline|
|
45
|
+
Thread.current[:pipeline] = pipeline
|
46
|
+
begin
|
47
|
+
yield
|
48
|
+
ensure
|
49
|
+
Thread.current[:pipeline] = nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def with(options = NO_OPTIONS, &block)
|
57
|
+
pipeline = Thread.current[:pipeline]
|
58
|
+
if pipeline
|
59
|
+
yield pipeline
|
60
|
+
else
|
61
|
+
super(options, &block)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
35
66
|
class Store
|
36
67
|
# Variable that holds the singleton instance
|
37
68
|
@instance = nil
|
@@ -67,7 +98,7 @@ module OpenC3
|
|
67
98
|
@redis_username = ENV['OPENC3_REDIS_USERNAME']
|
68
99
|
@redis_key = ENV['OPENC3_REDIS_PASSWORD']
|
69
100
|
@redis_url = "redis://#{ENV['OPENC3_REDIS_HOSTNAME']}:#{ENV['OPENC3_REDIS_PORT']}"
|
70
|
-
@redis_pool =
|
101
|
+
@redis_pool = StoreConnectionPool.new(size: pool_size) { build_redis() }
|
71
102
|
end
|
72
103
|
|
73
104
|
unless $openc3_redis_cluster
|
@@ -212,7 +243,7 @@ module OpenC3
|
|
212
243
|
def initialize(pool_size = 10)
|
213
244
|
super(pool_size)
|
214
245
|
@redis_url = "redis://#{ENV['OPENC3_REDIS_EPHEMERAL_HOSTNAME']}:#{ENV['OPENC3_REDIS_EPHEMERAL_PORT']}"
|
215
|
-
@redis_pool =
|
246
|
+
@redis_pool = StoreConnectionPool.new(size: pool_size) { build_redis() }
|
216
247
|
end
|
217
248
|
end
|
218
249
|
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.1'
|
4
4
|
module OpenC3
|
5
5
|
module Version
|
6
6
|
MAJOR = '5'
|
7
|
-
MINOR = '
|
8
|
-
PATCH = '
|
7
|
+
MINOR = '15'
|
8
|
+
PATCH = '1'
|
9
9
|
OTHER = ''
|
10
|
-
BUILD = '
|
10
|
+
BUILD = 'e825c03f698ac51170218e43cec3c3cecefe58fa'
|
11
11
|
end
|
12
|
-
VERSION = '5.
|
13
|
-
GEM_VERSION = '5.
|
12
|
+
VERSION = '5.15.1'
|
13
|
+
GEM_VERSION = '5.15.1'
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= tool_name %>",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.15.1",
|
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.1",
|
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.1",
|
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.1",
|
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.1",
|
15
15
|
"@astrouxds/astro-web-components": "7.20.0",
|
16
16
|
"axios": "1.6.5",
|
17
17
|
"date-fns": "2.30.0",
|
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "widget",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.15.1",
|
4
4
|
"private": true,
|
5
5
|
"scripts": {
|
6
6
|
"build": "vue-cli-service build --target lib --dest tools/widgets/<%= widget_name %> --formats umd-min <%= widget_path %> --name <%= widget_name %>"
|
7
7
|
},
|
8
8
|
"dependencies": {
|
9
|
-
"@openc3/tool-common": "5.
|
9
|
+
"@openc3/tool-common": "5.15.1",
|
10
10
|
"@astrouxds/astro-web-components": "7.20.0",
|
11
11
|
"vue": "2.7.16",
|
12
12
|
"vuetify": "2.7.1"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openc3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Melton
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-03-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -179,6 +179,20 @@ dependencies:
|
|
179
179
|
- - "~>"
|
180
180
|
- !ruby/object:Gem::Version
|
181
181
|
version: '5.0'
|
182
|
+
- !ruby/object:Gem::Dependency
|
183
|
+
name: hiredis-client
|
184
|
+
requirement: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - "~>"
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0.20'
|
189
|
+
type: :runtime
|
190
|
+
prerelease: false
|
191
|
+
version_requirements: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - "~>"
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0.20'
|
182
196
|
- !ruby/object:Gem::Dependency
|
183
197
|
name: rubyzip
|
184
198
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1167,7 +1181,6 @@ files:
|
|
1167
1181
|
- templates/tool_angular/tsconfig.app.json
|
1168
1182
|
- templates/tool_angular/tsconfig.json
|
1169
1183
|
- templates/tool_angular/tsconfig.spec.json
|
1170
|
-
- templates/tool_angular/yarn.lock
|
1171
1184
|
- templates/tool_react/.eslintrc
|
1172
1185
|
- templates/tool_react/.gitignore
|
1173
1186
|
- templates/tool_react/.prettierignore
|
@@ -1178,7 +1191,6 @@ files:
|
|
1178
1191
|
- templates/tool_react/src/root.component.js
|
1179
1192
|
- templates/tool_react/src/root.component.test.js
|
1180
1193
|
- templates/tool_react/webpack.config.js
|
1181
|
-
- templates/tool_react/yarn.lock
|
1182
1194
|
- templates/tool_svelte/.gitignore
|
1183
1195
|
- templates/tool_svelte/.prettierignore
|
1184
1196
|
- templates/tool_svelte/.prettierrc.js
|
@@ -1196,7 +1208,6 @@ files:
|
|
1196
1208
|
- templates/tool_svelte/src/services/openc3-api.js
|
1197
1209
|
- templates/tool_svelte/src/theme/_smui-theme.scss
|
1198
1210
|
- templates/tool_svelte/src/tool_name.js
|
1199
|
-
- templates/tool_svelte/yarn.lock
|
1200
1211
|
- templates/tool_vue/.browserslistrc
|
1201
1212
|
- templates/tool_vue/.env.standalone
|
1202
1213
|
- templates/tool_vue/.eslintrc.js
|
@@ -1211,7 +1222,6 @@ files:
|
|
1211
1222
|
- templates/tool_vue/src/router.js
|
1212
1223
|
- templates/tool_vue/src/tools/tool_name/tool_name.vue
|
1213
1224
|
- templates/tool_vue/vue.config.js
|
1214
|
-
- templates/tool_vue/yarn.lock
|
1215
1225
|
- templates/widget/.browserslistrc
|
1216
1226
|
- templates/widget/.eslintrc.js
|
1217
1227
|
- templates/widget/.nycrc
|
@@ -1222,7 +1232,6 @@ files:
|
|
1222
1232
|
- templates/widget/package.json
|
1223
1233
|
- templates/widget/src/Widget.vue
|
1224
1234
|
- templates/widget/vue.config.js
|
1225
|
-
- templates/widget/yarn.lock
|
1226
1235
|
homepage: https://github.com/OpenC3/cosmos
|
1227
1236
|
licenses:
|
1228
1237
|
- AGPL-3.0-only
|