openc3 5.10.1 → 5.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +3 -2
- data/data/config/target.yaml +9 -0
- data/ext/openc3/ext/packet/packet.c +3 -0
- data/ext/openc3/ext/reducer_microservice/extconf.rb +13 -0
- data/ext/openc3/ext/reducer_microservice/reducer_microservice.c +165 -0
- data/ext/openc3/ext/structure/structure.c +7 -9
- data/lib/openc3/accessors/accessor.rb +53 -3
- data/lib/openc3/accessors/binary_accessor.rb +16 -0
- data/lib/openc3/accessors/cbor_accessor.rb +3 -3
- data/lib/openc3/accessors/form_accessor.rb +78 -0
- data/lib/openc3/accessors/http_accessor.rb +145 -0
- data/lib/openc3/accessors/json_accessor.rb +19 -3
- data/lib/openc3/accessors/xml_accessor.rb +18 -1
- data/lib/openc3/accessors.rb +3 -1
- data/lib/openc3/config/config_parser.rb +7 -5
- data/lib/openc3/config/meta_config_parser.rb +1 -1
- data/lib/openc3/core_ext/string.rb +16 -1
- data/lib/openc3/interfaces/http_client_interface.rb +202 -0
- data/lib/openc3/interfaces/http_server_interface.rb +183 -0
- data/lib/openc3/interfaces/interface.rb +86 -16
- data/lib/openc3/interfaces/mqtt_interface.rb +6 -5
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +11 -11
- data/lib/openc3/interfaces/protocols/cobs_protocol.rb +7 -7
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +7 -7
- data/lib/openc3/interfaces/protocols/length_protocol.rb +6 -6
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +9 -5
- data/lib/openc3/interfaces/protocols/protocol.rb +8 -6
- data/lib/openc3/interfaces/protocols/slip_protocol.rb +8 -8
- data/lib/openc3/interfaces/protocols/template_protocol.rb +6 -7
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +4 -4
- data/lib/openc3/interfaces/simulated_target_interface.rb +2 -0
- data/lib/openc3/interfaces/stream_interface.rb +6 -4
- data/lib/openc3/interfaces/tcpip_server_interface.rb +2 -0
- data/lib/openc3/interfaces/udp_interface.rb +8 -5
- data/lib/openc3/interfaces.rb +2 -0
- data/lib/openc3/logs/buffered_packet_log_writer.rb +6 -7
- data/lib/openc3/logs/log_writer.rb +2 -10
- data/lib/openc3/logs/packet_log_constants.rb +13 -3
- data/lib/openc3/logs/packet_log_reader.rb +35 -98
- data/lib/openc3/logs/packet_log_writer.rb +24 -62
- data/lib/openc3/logs/text_log_writer.rb +32 -6
- data/lib/openc3/microservices/cleanup_microservice.rb +23 -16
- data/lib/openc3/microservices/decom_microservice.rb +8 -20
- data/lib/openc3/microservices/log_microservice.rb +3 -1
- data/lib/openc3/microservices/reaction_microservice.rb +22 -11
- data/lib/openc3/microservices/reducer_microservice.rb +174 -130
- data/lib/openc3/{models/notification_model.rb → microservices/scope_cleanup_microservice.rb} +20 -21
- data/lib/openc3/microservices/text_log_microservice.rb +2 -5
- data/lib/openc3/microservices/timeline_microservice.rb +0 -1
- data/lib/openc3/microservices/trigger_group_microservice.rb +0 -1
- data/lib/openc3/migrations/20230915000002_no_scope_log_messages.rb +44 -0
- data/lib/openc3/models/microservice_model.rb +1 -1
- data/lib/openc3/models/scope_model.rb +65 -34
- data/lib/openc3/models/target_model.rb +25 -5
- data/lib/openc3/models/tool_model.rb +14 -2
- data/lib/openc3/models/widget_model.rb +1 -1
- data/lib/openc3/packets/json_packet.rb +10 -2
- data/lib/openc3/packets/packet.rb +30 -9
- data/lib/openc3/packets/packet_config.rb +6 -2
- data/lib/openc3/packets/parsers/packet_item_parser.rb +11 -6
- data/lib/openc3/packets/structure.rb +19 -12
- data/lib/openc3/script/storage.rb +1 -1
- data/lib/openc3/script/web_socket_api.rb +17 -14
- data/lib/openc3/topics/telemetry_topic.rb +2 -1
- data/lib/openc3/utilities/bucket_utilities.rb +2 -0
- data/lib/openc3/utilities/cli_generator.rb +1 -1
- data/lib/openc3/utilities/logger.rb +62 -47
- data/lib/openc3/utilities/metric.rb +19 -1
- data/lib/openc3/utilities/sleeper.rb +3 -1
- data/lib/openc3/utilities/throttle.rb +76 -0
- data/lib/openc3/version.rb +6 -6
- data/templates/tool_angular/package.json +20 -20
- data/templates/tool_angular/yarn.lock +112 -106
- data/templates/tool_react/package.json +16 -18
- data/templates/tool_react/yarn.lock +977 -664
- data/templates/tool_svelte/.prettierrc.js +5 -0
- data/templates/tool_svelte/package.json +18 -18
- data/templates/tool_svelte/src/services/cable.js +1 -1
- data/templates/tool_svelte/src/services/openc3-api.js +173 -173
- data/templates/tool_svelte/yarn.lock +767 -665
- data/templates/tool_vue/package.json +10 -10
- data/templates/tool_vue/yarn.lock +225 -43
- data/templates/widget/package.json +10 -10
- data/templates/widget/yarn.lock +223 -46
- metadata +41 -4
- data/lib/openc3/topics/notifications_topic.rb +0 -31
@@ -190,7 +190,7 @@ module OpenC3
|
|
190
190
|
|
191
191
|
# Base class for script-runner-api websockets - Do not use directly
|
192
192
|
class ScriptWebSocketApi < WebSocketApi
|
193
|
-
def initialize(url: nil, write_timeout: 10.0, read_timeout: 10.0, connect_timeout: 5.0, authentication: nil, scope: $
|
193
|
+
def initialize(url: nil, write_timeout: 10.0, read_timeout: 10.0, connect_timeout: 5.0, authentication: nil, scope: $openc3_scope)
|
194
194
|
url = generate_url() unless url
|
195
195
|
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
196
196
|
end
|
@@ -217,23 +217,15 @@ module OpenC3
|
|
217
217
|
|
218
218
|
# Log Messages WebSocket
|
219
219
|
class MessagesWebSocketApi < CmdTlmWebSocketApi
|
220
|
-
def initialize(history_count: 0, url: nil, write_timeout: 10.0, read_timeout: 10.0, connect_timeout: 5.0, authentication: nil, scope: $openc3_scope)
|
220
|
+
def initialize(history_count: 0, start_time: nil, end_time: nil, severity: nil, types: nil, url: nil, write_timeout: 10.0, read_timeout: 10.0, connect_timeout: 5.0, authentication: nil, scope: $openc3_scope)
|
221
221
|
@identifier = {
|
222
222
|
channel: "MessagesChannel",
|
223
223
|
history_count: history_count
|
224
224
|
}
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
# Notifications WebSocket
|
230
|
-
class NotificationsWebSocketApi < CmdTlmWebSocketApi
|
231
|
-
def initialize(history_count: 0, start_offset: nil, url: nil, write_timeout: 10.0, read_timeout: 10.0, connect_timeout: 5.0, authentication: nil, scope: $openc3_scope)
|
232
|
-
@identifier = {
|
233
|
-
channel: "NotificationsChannel",
|
234
|
-
history_count: history_count,
|
235
|
-
start_offset: start_offset
|
236
|
-
}
|
225
|
+
@identifier['start_time'] = start_time if start_time
|
226
|
+
@identifier['end_time'] = end_time if end_time
|
227
|
+
@identifier['severity'] = severity if severity
|
228
|
+
@identifier['types'] = types if types
|
237
229
|
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
238
230
|
end
|
239
231
|
end
|
@@ -425,3 +417,14 @@ end
|
|
425
417
|
#
|
426
418
|
# # Warning this saves all data to RAM. Do not use for large queries
|
427
419
|
# data = OpenC3::StreamingWebSocketApi.read_all(items: ['DECOM__TLM__INST__HEALTH_STATUS__TEMP1__CONVERTED', 'DECOM__TLM__INST__HEALTH_STATUS__TEMP2__CONVERTED'], start_time: Time.now - 30, end_time: Time.now + 30)
|
420
|
+
|
421
|
+
# $openc3_scope = 'DEFAULT'
|
422
|
+
# OpenC3::MessagesWebSocketApi.new(history_count: 0, start_time: (Time.now - 86400).to_nsec_from_epoch, end_time: (Time.now - 60).to_nsec_from_epoch) do |api|
|
423
|
+
# 500.times do
|
424
|
+
# # Note returns batch array
|
425
|
+
# data = api.read
|
426
|
+
# return if not data or data.length == 0
|
427
|
+
# puts "\nReceived #{data.length} log messages:"
|
428
|
+
# puts data
|
429
|
+
# end
|
430
|
+
# end
|
@@ -32,8 +32,9 @@ module OpenC3
|
|
32
32
|
:target_name => packet.target_name,
|
33
33
|
:packet_name => packet.packet_name,
|
34
34
|
:received_count => packet.received_count,
|
35
|
-
:buffer => packet.buffer(false)
|
35
|
+
:buffer => packet.buffer(false)
|
36
36
|
}
|
37
|
+
msg_hash[:extra] = JSON.generate(packet.extra.as_json, allow_nan: true) if packet.extra
|
37
38
|
Topic.write_topic("#{scope}__TELEMETRY__{#{packet.target_name}}__#{packet.packet_name}", msg_hash)
|
38
39
|
end
|
39
40
|
end
|
@@ -58,6 +58,8 @@ module OpenC3
|
|
58
58
|
# @param start_time [Time|nil] Ruby time to find files after. nil means no start (first file on).
|
59
59
|
# @param end_time [Time|nil] Ruby time to find files before. nil means no end (up to last file).
|
60
60
|
# @param overlap [Boolean] Whether to include files which overlap the start and end time
|
61
|
+
# if true, file can be partially in the time range
|
62
|
+
# if false, file must be completely in the time range
|
61
63
|
# @param max_request [Integer] How many files to request in each API call
|
62
64
|
# @param max_total [Integer] Total number of files before stopping API requests
|
63
65
|
def self.files_between_time(bucket, prefix, start_time, end_time, file_suffix: nil,
|
@@ -51,7 +51,7 @@ module OpenC3
|
|
51
51
|
FileUtils.mkdir(base_name) unless File.exist?(base_name)
|
52
52
|
next
|
53
53
|
end
|
54
|
-
output = ERB.new(File.read(file), trim_mode: "-").result(the_binding)
|
54
|
+
output = ERB.new(File.read(file).comment_erb(), trim_mode: "-").result(the_binding)
|
55
55
|
File.open(base_name, 'w') do |file|
|
56
56
|
file.write output
|
57
57
|
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 2023, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -44,11 +44,9 @@ module OpenC3
|
|
44
44
|
# @return [String] Microservice name
|
45
45
|
attr_reader :microservice_name
|
46
46
|
|
47
|
-
# @return [String] Scope
|
48
|
-
instance_attr_accessor :scope
|
49
|
-
|
50
47
|
@@mutex = Mutex.new
|
51
48
|
@@instance = nil
|
49
|
+
@@scope = ENV['OPENC3_SCOPE']
|
52
50
|
|
53
51
|
# DEBUG only prints DEBUG messages
|
54
52
|
DEBUG = ::Logger::DEBUG
|
@@ -67,11 +65,15 @@ module OpenC3
|
|
67
65
|
ERROR_SEVERITY_STRING = 'ERROR'
|
68
66
|
FATAL_SEVERITY_STRING = 'FATAL'
|
69
67
|
|
68
|
+
# Types
|
69
|
+
LOG = 'log'
|
70
|
+
NOTIFICATION = 'notification'
|
71
|
+
ALERT = 'alert'
|
72
|
+
|
70
73
|
# @param level [Integer] The initial logging level
|
71
74
|
def initialize(level = Logger::INFO)
|
72
75
|
@stdout = true
|
73
76
|
@level = level
|
74
|
-
@scope = nil
|
75
77
|
@detail_string = nil
|
76
78
|
@container_name = Socket.gethostname
|
77
79
|
@microservice_name = nil
|
@@ -95,68 +97,53 @@ module OpenC3
|
|
95
97
|
# below the method name log level.
|
96
98
|
# @param block [Proc] Block to call which should return a string to append
|
97
99
|
# to the log message
|
98
|
-
def debug(message = nil, scope:
|
99
|
-
log_message(DEBUG_SEVERITY_STRING, message, scope: scope, user: user, &block) if @level <= DEBUG
|
100
|
+
def debug(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
101
|
+
log_message(DEBUG_SEVERITY_STRING, message, scope: scope, user: user, type: type, url: url, &block) if @level <= DEBUG
|
100
102
|
end
|
101
103
|
|
102
104
|
# (see #debug)
|
103
|
-
def info(message = nil, scope:
|
104
|
-
log_message(INFO_SEVERITY_STRING, message, scope: scope, user: user, &block) if @level <= INFO
|
105
|
+
def info(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
106
|
+
log_message(INFO_SEVERITY_STRING, message, scope: scope, user: user, type: type, url: url, &block) if @level <= INFO
|
105
107
|
end
|
106
108
|
|
107
109
|
# (see #debug)
|
108
|
-
def warn(message = nil, scope:
|
109
|
-
log_message(WARN_SEVERITY_STRING, message, scope: scope, user: user, &block) if @level <= WARN
|
110
|
+
def warn(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
111
|
+
log_message(WARN_SEVERITY_STRING, message, scope: scope, user: user, type: type, url: url, &block) if @level <= WARN
|
110
112
|
end
|
111
113
|
|
112
114
|
# (see #debug)
|
113
|
-
def error(message = nil, scope:
|
114
|
-
log_message(ERROR_SEVERITY_STRING, message, scope: scope, user: user, &block) if @level <= ERROR
|
115
|
+
def error(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
116
|
+
log_message(ERROR_SEVERITY_STRING, message, scope: scope, user: user, type: type, url: url, &block) if @level <= ERROR
|
115
117
|
end
|
116
118
|
|
117
119
|
# (see #debug)
|
118
|
-
def fatal(message = nil, scope:
|
119
|
-
log_message(FATAL_SEVERITY_STRING, message, scope: scope, user: user, &block) if @level <= FATAL
|
120
|
+
def fatal(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
121
|
+
log_message(FATAL_SEVERITY_STRING, message, scope: scope, user: user, type: type, url: url, &block) if @level <= FATAL
|
120
122
|
end
|
121
123
|
|
122
124
|
# (see #debug)
|
123
|
-
def self.debug(message = nil, scope:
|
124
|
-
|
125
|
-
args[:scope] = scope if scope
|
126
|
-
args[:user] = user if user
|
127
|
-
self.instance.debug(message, **args, &block)
|
125
|
+
def self.debug(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
126
|
+
self.instance.debug(message, scope: scope, user: user, type: type, url: url, &block)
|
128
127
|
end
|
129
128
|
|
130
129
|
# (see #debug)
|
131
|
-
def self.info(message = nil, scope:
|
132
|
-
|
133
|
-
args[:scope] = scope if scope
|
134
|
-
args[:user] = user if user
|
135
|
-
self.instance.info(message, **args, &block)
|
130
|
+
def self.info(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
131
|
+
self.instance.info(message, scope: scope, user: user, type: type, url: url, &block)
|
136
132
|
end
|
137
133
|
|
138
134
|
# (see #debug)
|
139
|
-
def self.warn(message = nil, scope:
|
140
|
-
|
141
|
-
args[:scope] = scope if scope
|
142
|
-
args[:user] = user if user
|
143
|
-
self.instance.warn(message, **args, &block)
|
135
|
+
def self.warn(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
136
|
+
self.instance.warn(message, scope: scope, user: user, type: type, url: url, &block)
|
144
137
|
end
|
145
138
|
|
146
139
|
# (see #debug)
|
147
|
-
def self.error(message = nil, scope:
|
148
|
-
|
149
|
-
args[:scope] = scope if scope
|
150
|
-
args[:user] = user if user
|
151
|
-
self.instance.error(message, **args, &block)
|
140
|
+
def self.error(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
141
|
+
self.instance.error(message, scope: scope, user: user, type: type, url: url, &block)
|
152
142
|
end
|
153
143
|
|
154
144
|
# (see #debug)
|
155
|
-
def self.fatal(message = nil, scope:
|
156
|
-
|
157
|
-
args[:scope] = scope if scope
|
158
|
-
args[:user] = user if user
|
159
|
-
self.instance.fatal(message, **args, &block)
|
145
|
+
def self.fatal(message = nil, scope: @@scope, user: nil, type: LOG, url: nil, &block)
|
146
|
+
self.instance.fatal(message, scope: scope, user: user, type: type, url: url, &block)
|
160
147
|
end
|
161
148
|
|
162
149
|
# @return [Logger] The logger instance
|
@@ -169,11 +156,28 @@ module OpenC3
|
|
169
156
|
@@instance
|
170
157
|
end
|
171
158
|
|
159
|
+
def self.scope
|
160
|
+
return @@scope
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.scope=(scope)
|
164
|
+
@@scope = scope
|
165
|
+
end
|
166
|
+
|
167
|
+
def scope
|
168
|
+
return @@scope
|
169
|
+
end
|
170
|
+
|
171
|
+
def scope=(scope)
|
172
|
+
@@scope = scope
|
173
|
+
end
|
174
|
+
|
172
175
|
protected
|
173
176
|
|
174
|
-
def log_message(severity_string, message, scope:, user:)
|
177
|
+
def log_message(severity_string, message, scope:, user:, type:, url:)
|
175
178
|
@@mutex.synchronize do
|
176
|
-
|
179
|
+
time = Time.now
|
180
|
+
data = { time: time.to_nsec_from_epoch, '@timestamp' => time.xmlschema(3), severity: severity_string }
|
177
181
|
data[:microservice_name] = @microservice_name if @microservice_name
|
178
182
|
data[:detail] = @detail_string if @detail_string
|
179
183
|
data[:user] = user['username'] || 'Unknown' if user # EE: If a user is passed, put its name ('Unknown' if it doesn't have a name). Don't include user data if no user was passed
|
@@ -182,17 +186,28 @@ module OpenC3
|
|
182
186
|
end
|
183
187
|
data[:container_name] = @container_name
|
184
188
|
data[:log] = message
|
189
|
+
data[:type] = type
|
190
|
+
data[:url] = url if url
|
185
191
|
if @stdout
|
186
|
-
|
187
|
-
|
192
|
+
case severity_string
|
193
|
+
when WARN_SEVERITY_STRING, ERROR_SEVERITY_STRING, FATAL_SEVERITY_STRING
|
194
|
+
if ENV['OPENC3_LOG_STDERR']
|
195
|
+
$stderr.puts data.as_json(:allow_nan => true).to_json(:allow_nan => true)
|
196
|
+
$stderr.flush
|
197
|
+
else
|
198
|
+
$stdout.puts data.as_json(:allow_nan => true).to_json(:allow_nan => true)
|
199
|
+
$stdout.flush
|
200
|
+
end
|
201
|
+
else
|
202
|
+
$stdout.puts data.as_json(:allow_nan => true).to_json(:allow_nan => true)
|
203
|
+
$stdout.flush
|
204
|
+
end
|
188
205
|
end
|
189
206
|
unless @no_store
|
190
207
|
if scope
|
191
208
|
Topic.write_topic("#{scope}__openc3_log_messages", data)
|
192
209
|
else
|
193
|
-
|
194
|
-
# so it must be limited to prevent unbounded stream growth
|
195
|
-
Topic.write_topic("openc3_log_messages", data, '*', 1000)
|
210
|
+
Topic.write_topic("NOSCOPE__openc3_log_messages", data)
|
196
211
|
end
|
197
212
|
end
|
198
213
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2023 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# This program is free software; you can modify and/or redistribute it
|
@@ -38,6 +38,9 @@ module OpenC3
|
|
38
38
|
# Sleeper used to delay update thread
|
39
39
|
@@update_sleeper = nil
|
40
40
|
|
41
|
+
# Objects with a generate method to be called on each metric cycle (to generate metrics)
|
42
|
+
@@update_generators = []
|
43
|
+
|
41
44
|
attr_reader :microservice
|
42
45
|
attr_reader :scope
|
43
46
|
attr_reader :data
|
@@ -83,7 +86,12 @@ module OpenC3
|
|
83
86
|
@@update_sleeper = Sleeper.new
|
84
87
|
while true
|
85
88
|
start_time = Time.now
|
89
|
+
|
86
90
|
@@mutex.synchronize do
|
91
|
+
@@update_generators.each do |generator|
|
92
|
+
generator.generate(@@instances[0])
|
93
|
+
end
|
94
|
+
|
87
95
|
@@instances.each do |instance|
|
88
96
|
instance.mutex.synchronize do
|
89
97
|
json = {}
|
@@ -116,5 +124,15 @@ module OpenC3
|
|
116
124
|
|
117
125
|
def graceful_kill
|
118
126
|
end
|
127
|
+
|
128
|
+
def self.add_update_generator(object)
|
129
|
+
@@update_generators << object
|
130
|
+
end
|
119
131
|
end
|
120
132
|
end
|
133
|
+
|
134
|
+
begin
|
135
|
+
require 'openc3-enterprise/utilities/metric'
|
136
|
+
rescue LoadError
|
137
|
+
# Open Source Edition - Do nothing here
|
138
|
+
end
|
@@ -17,7 +17,7 @@
|
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
module OpenC3
|
@@ -37,6 +37,7 @@ module OpenC3
|
|
37
37
|
def sleep(seconds)
|
38
38
|
read_ready, _ = IO.select(@readers, nil, nil, seconds)
|
39
39
|
if read_ready && read_ready.include?(@pipe_reader)
|
40
|
+
@pipe_reader.close unless @pipe_reader.closed?
|
40
41
|
return true
|
41
42
|
else
|
42
43
|
return false
|
@@ -48,6 +49,7 @@ module OpenC3
|
|
48
49
|
if !@canceled
|
49
50
|
@canceled = true
|
50
51
|
@pipe_writer.write('.')
|
52
|
+
@pipe_writer.close
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2023 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
# Usage:
|
20
|
+
# throttle = OpenC3::Throttle.new(50.0) # Use max 50% cpu for work
|
21
|
+
#
|
22
|
+
# throttle.reset # Necessary if there are large periods of idle between hard work
|
23
|
+
# 1000.times do
|
24
|
+
# throttle.start
|
25
|
+
# # Do one iteration of cpu itensive work here
|
26
|
+
# # complete will sleep if necessary to not use too much CPU
|
27
|
+
# throttle.complete
|
28
|
+
# end
|
29
|
+
|
30
|
+
module OpenC3
|
31
|
+
class Throttle
|
32
|
+
MIN_SLEEP_SECONDS = 0.001
|
33
|
+
MAX_SLEEP_SECONDS = 0.100
|
34
|
+
|
35
|
+
attr_reader :reset_time
|
36
|
+
attr_reader :total_sleep_time
|
37
|
+
|
38
|
+
# @param max_cpu_utilization [Float] 0.0-100.0
|
39
|
+
def initialize(max_cpu_utilization)
|
40
|
+
@max_cpu_utilization = Float(max_cpu_utilization)
|
41
|
+
raise ArgumentError "max_cpu_utilization must be between 0.0 and 100.0" if @max_cpu_utilization > 100.0 or @max_cpu_utilization < 0.0
|
42
|
+
@max_cpu_utilization /= 100.0 # Normalize
|
43
|
+
reset()
|
44
|
+
end
|
45
|
+
|
46
|
+
def reset
|
47
|
+
@reset_time = Time.now
|
48
|
+
@total_sleep_time = 0
|
49
|
+
end
|
50
|
+
|
51
|
+
def throttle_sleep
|
52
|
+
return if @max_cpu_utilization >= 1.0
|
53
|
+
total_time = Time.now - @reset_time
|
54
|
+
if total_time > 0
|
55
|
+
cpu_utilization = 1.0 - (@total_sleep_time / total_time)
|
56
|
+
if cpu_utilization > @max_cpu_utilization
|
57
|
+
# Need to throttle
|
58
|
+
# max_cpu_utilization = sleep_time + total_sleep_time
|
59
|
+
# ----------------------------
|
60
|
+
# total_time
|
61
|
+
#
|
62
|
+
# (max_cpu_utilization * total_time) = sleep_time + total_sleep_time
|
63
|
+
#
|
64
|
+
# sleep_time = (max_cpu_utilization * total_time) - total_sleep_time
|
65
|
+
#
|
66
|
+
sleep_time = (@max_cpu_utilization * total_time) - @total_sleep_time
|
67
|
+
if sleep_time > MIN_SLEEP_SECONDS
|
68
|
+
sleep_time = MAX_SLEEP_SECONDS if sleep_time > MAX_SLEEP_SECONDS
|
69
|
+
sleep(sleep_time)
|
70
|
+
@total_sleep_time += sleep_time
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
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.11.0'
|
4
4
|
module OpenC3
|
5
5
|
module Version
|
6
6
|
MAJOR = '5'
|
7
|
-
MINOR = '
|
8
|
-
PATCH = '
|
7
|
+
MINOR = '11'
|
8
|
+
PATCH = '0'
|
9
9
|
OTHER = ''
|
10
|
-
BUILD = '
|
10
|
+
BUILD = 'f994eee0c2fadfc67ffbf0865ba798ed11ec1f5c'
|
11
11
|
end
|
12
|
-
VERSION = '5.
|
13
|
-
GEM_VERSION = '5.
|
12
|
+
VERSION = '5.11.0'
|
13
|
+
GEM_VERSION = '5.11.0'
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= tool_name %>",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.11.0",
|
4
4
|
"scripts": {
|
5
5
|
"ng": "ng",
|
6
6
|
"start": "ng serve",
|
@@ -12,36 +12,36 @@
|
|
12
12
|
},
|
13
13
|
"private": true,
|
14
14
|
"dependencies": {
|
15
|
-
"@openc3/tool-common": "5.
|
16
|
-
"@angular/animations": "^16.2.
|
17
|
-
"@angular/cdk": "^16.2.
|
18
|
-
"@angular/common": "^16.2.
|
19
|
-
"@angular/compiler": "^16.2.
|
20
|
-
"@angular/core": "^16.2.
|
21
|
-
"@angular/forms": "^16.2.
|
22
|
-
"@angular/material": "16.2.
|
23
|
-
"@angular/platform-browser": "^16.2.
|
24
|
-
"@angular/platform-browser-dynamic": "^16.2.
|
25
|
-
"@angular/router": "^16.2.
|
15
|
+
"@openc3/tool-common": "5.11.0",
|
16
|
+
"@angular/animations": "^16.2.4",
|
17
|
+
"@angular/cdk": "^16.2.3",
|
18
|
+
"@angular/common": "^16.2.4",
|
19
|
+
"@angular/compiler": "^16.2.4",
|
20
|
+
"@angular/core": "^16.2.4",
|
21
|
+
"@angular/forms": "^16.2.4",
|
22
|
+
"@angular/material": "16.2.3",
|
23
|
+
"@angular/platform-browser": "^16.2.4",
|
24
|
+
"@angular/platform-browser-dynamic": "^16.2.4",
|
25
|
+
"@angular/router": "^16.2.4",
|
26
26
|
"rxjs": "~7.8.0",
|
27
27
|
"single-spa": ">=5.9.5",
|
28
28
|
"single-spa-angular": "^8.1.0",
|
29
|
-
"tslib": "^2.6.
|
30
|
-
"zone.js": "~0.13.
|
29
|
+
"tslib": "^2.6.2",
|
30
|
+
"zone.js": "~0.13.3"
|
31
31
|
},
|
32
32
|
"devDependencies": {
|
33
|
-
"@angular-builders/custom-webpack": "16.0.
|
34
|
-
"@angular-devkit/build-angular": "^16.2.
|
35
|
-
"@angular/cli": "~16.2.
|
36
|
-
"@angular/compiler-cli": "^16.2.
|
33
|
+
"@angular-builders/custom-webpack": "16.0.1",
|
34
|
+
"@angular-devkit/build-angular": "^16.2.1",
|
35
|
+
"@angular/cli": "~16.2.1",
|
36
|
+
"@angular/compiler-cli": "^16.2.4",
|
37
37
|
"@types/jasmine": "~4.3.0",
|
38
|
-
"jasmine-core": "~5.1.
|
38
|
+
"jasmine-core": "~5.1.1",
|
39
39
|
"karma": "~6.4.0",
|
40
40
|
"karma-chrome-launcher": "~3.2.0",
|
41
41
|
"karma-coverage": "~2.2.0",
|
42
42
|
"karma-jasmine": "~5.1.0",
|
43
43
|
"karma-jasmine-html-reporter": "~2.1.0",
|
44
44
|
"style-loader": "^3.3.1",
|
45
|
-
"typescript": "~5.
|
45
|
+
"typescript": "~5.2.2"
|
46
46
|
}
|
47
47
|
}
|