openc3 5.11.0 → 5.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: beada8d3ae31acc7a45fff23d454f4667b552a5de293f6c17f6da72626dd8490
4
- data.tar.gz: 950b07bf2f6a3173284d41a77ae7abf4cf6f9582a885dbedc585d50001fadcd8
3
+ metadata.gz: 5026df00ed04704e22029423bc09cae31eaebb798517ee02f1fcef3d60c4dfc0
4
+ data.tar.gz: 96c671d4a686c15d1db84489528f0551cb0cb54b42d21410839fc65f927c5360
5
5
  SHA512:
6
- metadata.gz: 7b0e9f874d5a88c167ba9bd78c3718d1b646ab80560106e01fb109189c27d6b399a3f51531b23815129ea24f4b9194770c9448d8e4be832c0926a6f5b8c3f9ad
7
- data.tar.gz: e5c20e0648e27b311de33c0d06eb27bb229110eac0fcf197619dac6a3232b239334cbda07bf3f79e88ddb7425b773191c04f9929883a6042b36633c99924285a
6
+ metadata.gz: 76cdc1efc5b5094da9c84fde2ce27fe9b850f594a2ffa09ab736b6ec98f3f1a73c20700ac4e409dd1c3632cdb208e1695b37aada33af2dce548633b771035021
7
+ data.tar.gz: 4142f4251262cc43f60bdfa4d54300e2282a2c2759991ebfd623a046c1e97a8ac929aec764b05fae59fa874b99957bfc492199219e9ec70dfa3a9315afb9206a
data/README.md CHANGED
@@ -17,7 +17,6 @@ set OPENC3_REDIS_USERNAME=openc3
17
17
  set OPENC3_REDIS_PASSWORD=openc3password
18
18
  set OPENC3_BUCKET_USERNAME=openc3minio
19
19
  set OPENC3_BUCKET_PASSWORD=openc3miniopassword
20
- set OPENC3_SERVICE_PASSWORD=openc3service
21
20
  set OPENC3_SR_REDIS_USERNAME=scriptrunner
22
21
  set OPENC3_SR_REDIS_PASSWORD=scriptrunnerpassword
23
22
  set OPENC3_SR_BUCKET_USERNAME=scriptrunnerminio
@@ -31,7 +30,6 @@ OPENC3_REDIS_USERNAME=openc3
31
30
  OPENC3_REDIS_PASSWORD=openc3password
32
31
  OPENC3_BUCKET_USERNAME=openc3minio
33
32
  OPENC3_BUCKET_PASSWORD=openc3miniopassword
34
- OPENC3_SERVICE_PASSWORD=openc3service
35
33
  OPENC3_SR_REDIS_USERNAME=scriptrunner
36
34
  OPENC3_SR_REDIS_PASSWORD=scriptrunnerpassword
37
35
  OPENC3_SR_BUCKET_USERNAME=scriptrunnerminio
@@ -36,9 +36,12 @@ module OpenC3
36
36
 
37
37
  DURATION_METRICS = {}
38
38
  DURATION_METRICS['decom_duration_seconds'] = 0.0
39
- DURATION_METRICS['reducer_minute_processing_seconds'] = 0
40
- DURATION_METRICS['reducer_hour_processing_seconds'] = 0
41
- DURATION_METRICS['reducer_day_processing_seconds'] = 0
39
+ DURATION_METRICS['reducer_minute_processing_sample_seconds'] = 0.0
40
+ DURATION_METRICS['reducer_hour_processing_sample_seconds'] = 0.0
41
+ DURATION_METRICS['reducer_day_processing_sample_seconds'] = 0.0
42
+ DURATION_METRICS['reducer_minute_processing_max_seconds'] = 0.0
43
+ DURATION_METRICS['reducer_hour_processing_max_seconds'] = 0.0
44
+ DURATION_METRICS['reducer_day_processing_max_seconds'] = 0.0
42
45
 
43
46
  SUM_METRICS = {}
44
47
  SUM_METRICS['cleanup_total'] = 0
@@ -51,8 +54,12 @@ module OpenC3
51
54
  SUM_METRICS['log_total'] = 0
52
55
  SUM_METRICS['log_error_total'] = 0
53
56
  SUM_METRICS['periodic_total'] = 0
54
- SUM_METRICS['reducer_total'] = 0
55
- SUM_METRICS['reducer_error_total'] = 0
57
+ SUM_METRICS['reducer_minute_total'] = 0
58
+ SUM_METRICS['reducer_hour_total'] = 0
59
+ SUM_METRICS['reducer_day_total'] = 0
60
+ SUM_METRICS['reducer_minute_error_total'] = 0
61
+ SUM_METRICS['reducer_hour_error_total'] = 0
62
+ SUM_METRICS['reducer_day_error_total'] = 0
56
63
  SUM_METRICS['router_cmd_total'] = 0
57
64
  SUM_METRICS['router_tlm_total'] = 0
58
65
  SUM_METRICS['router_directive_total'] = 0
@@ -53,7 +53,7 @@ module OpenC3
53
53
  # generate the auth object
54
54
  def _generate_auth
55
55
  if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
56
- if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
56
+ if ENV['OPENC3_API_PASSWORD']
57
57
  return OpenC3Authentication.new()
58
58
  else
59
59
  return nil
@@ -72,7 +72,7 @@ module OpenC3
72
72
  # generate the auth object
73
73
  def generate_auth
74
74
  if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
75
- if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
75
+ if ENV['OPENC3_API_PASSWORD']
76
76
  return OpenC3Authentication.new()
77
77
  else
78
78
  return nil
@@ -281,7 +281,9 @@ module OpenC3
281
281
  OpenC3.handle_critical_exception(err)
282
282
  end
283
283
 
284
- def prepare_write(time_nsec_since_epoch, data_length, redis_topic = nil, redis_offset = nil, allow_new_file: true)
284
+ # @enforce_time_order requires the timestamps on each write to be greater than the previous
285
+ # process_out_of_order ignores the timestamps for the current entry (used to ignore timestamps on metadata entries, vs actual packets)
286
+ def prepare_write(time_nsec_since_epoch, data_length, redis_topic = nil, redis_offset = nil, allow_new_file: true, process_out_of_order: true)
285
287
  # This check includes logging_enabled again because it might have changed since we acquired the mutex
286
288
  # Ensures new files based on size, and ensures always increasing time order in files
287
289
  if @logging_enabled
@@ -291,7 +293,7 @@ module OpenC3
291
293
  elsif @cycle_size and ((@file_size + data_length) > @cycle_size)
292
294
  Logger.debug("Log writer start new file due to cycle size #{@cycle_size}")
293
295
  start_new_file() if allow_new_file
294
- elsif @enforce_time_order and @previous_time_nsec_since_epoch and (@previous_time_nsec_since_epoch > time_nsec_since_epoch)
296
+ elsif process_out_of_order and @enforce_time_order and @previous_time_nsec_since_epoch and (@previous_time_nsec_since_epoch > time_nsec_since_epoch)
295
297
  # Warning: Creating new files here can cause lots of files to be created if packets make it through out of order
296
298
  # Changed to just a error to prevent file thrashing
297
299
  unless @out_of_order
@@ -301,7 +303,7 @@ module OpenC3
301
303
  end
302
304
  end
303
305
  @last_offsets[redis_topic] = redis_offset if redis_topic and redis_offset # This is needed for the redis offset marker entry at the end of the log file
304
- @previous_time_nsec_since_epoch = time_nsec_since_epoch
306
+ @previous_time_nsec_since_epoch = time_nsec_since_epoch if process_out_of_order
305
307
  end
306
308
 
307
309
  # Closing a log file isn't critical so we just log an error. NOTE: This also trims the Redis stream
@@ -95,7 +95,14 @@ module OpenC3
95
95
 
96
96
  @mutex.lock if take_mutex
97
97
  begin
98
- prepare_write(time_nsec_since_epoch, data.length, redis_topic, redis_offset, allow_new_file: allow_new_file)
98
+ if entry_type == :RAW_PACKET or entry_type == :JSON_PACKET
99
+ # Only care about the timestamps on the real packets being in order
100
+ process_out_of_order = true
101
+ else
102
+ # Metadata timestamps don't matter
103
+ process_out_of_order = false
104
+ end
105
+ prepare_write(time_nsec_since_epoch, data.length, redis_topic, redis_offset, allow_new_file: allow_new_file, process_out_of_order: process_out_of_order)
99
106
  write_entry(entry_type, cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, data, id, received_time_nsec_since_epoch: received_time_nsec_since_epoch, extra: extra) if @file
100
107
  ensure
101
108
  @mutex.unlock if take_mutex
@@ -30,6 +30,7 @@ require 'openc3/models/reducer_model'
30
30
  require 'openc3/logs/buffered_packet_log_writer'
31
31
  require 'openc3/ext/reducer_microservice' if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
32
32
  require 'rufus-scheduler'
33
+ require 'thread'
33
34
 
34
35
  module OpenC3
35
36
  class ReducerState
@@ -75,9 +76,9 @@ module OpenC3
75
76
  end
76
77
 
77
78
  class ReducerMicroservice < Microservice
78
- MINUTE_METRIC = 'reducer_minute_processing_seconds'
79
- HOUR_METRIC = 'reducer_hour_processing_seconds'
80
- DAY_METRIC = 'reducer_day_processing_seconds'
79
+ MINUTE_METRIC = 'reducer_minute_processing'
80
+ HOUR_METRIC = 'reducer_hour_processing'
81
+ DAY_METRIC = 'reducer_day_processing'
81
82
 
82
83
  # How long to wait for any currently running jobs to complete before killing them
83
84
  SHUTDOWN_DELAY_SECS = 5
@@ -106,14 +107,28 @@ module OpenC3
106
107
  end
107
108
  end
108
109
 
109
- @buffer_depth = 10 unless @buffer_depth
110
+ @buffer_depth = 60 unless @buffer_depth
110
111
  @max_cpu_utilization = 30.0 unless @max_cpu_utilization
111
112
  @target_name = name.split('__')[-1]
112
113
  @packet_logs = {}
114
+ @mutex = Mutex.new
115
+ @previous_metrics = {}
113
116
 
114
117
  @error_count = 0
115
- @metric.set(name: 'reducer_total', value: @count, type: 'counter')
116
- @metric.set(name: 'reducer_error_total', value: @error_count, type: 'counter')
118
+
119
+ # Initialize metrics
120
+ @metric.set(name: 'reducer_minute_total', value: 0, type: 'counter')
121
+ @metric.set(name: 'reducer_hour_total', value: 0, type: 'counter')
122
+ @metric.set(name: 'reducer_day_total', value: 0, type: 'counter')
123
+ @metric.set(name: 'reducer_minute_error_total', value: 0, type: 'counter')
124
+ @metric.set(name: 'reducer_hour_error_total', value: 0, type: 'counter')
125
+ @metric.set(name: 'reducer_day_error_total', value: 0, type: 'counter')
126
+ @metric.set(name: 'reducer_minute_processing_sample_seconds', value: 0.0, type: 'gauge', unit: 'seconds')
127
+ @metric.set(name: 'reducer_hour_processing_sample_seconds', value: 0.0, type: 'gauge', unit: 'seconds')
128
+ @metric.set(name: 'reducer_day_processing_sample_seconds', value: 0.0, type: 'gauge', unit: 'seconds')
129
+ @metric.set(name: 'reducer_minute_processing_max_seconds', value: 0.0, type: 'gauge', unit: 'seconds')
130
+ @metric.set(name: 'reducer_hour_processing_max_seconds', value: 0.0, type: 'gauge', unit: 'seconds')
131
+ @metric.set(name: 'reducer_day_processing_max_seconds', value: 0.0, type: 'gauge', unit: 'seconds')
117
132
  end
118
133
 
119
134
  def run
@@ -155,41 +170,65 @@ module OpenC3
155
170
 
156
171
  def metric(name)
157
172
  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
158
- yield
173
+ processed = yield
159
174
  elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start # seconds as a float
160
- @metric.set(name: name, value: elapsed, type: 'gauge', unit: 'seconds')
175
+ if processed
176
+ sample_name = name + '_sample_seconds'
177
+ @metric.set(name: sample_name, value: elapsed, type: 'gauge', unit: 'seconds')
178
+ max_name = name + '_max_seconds'
179
+ previous_max = @previous_metrics[max_name] || 0.0
180
+ if elapsed > previous_max
181
+ @metric.set(name: max_name, value: elapsed, type: 'gauge', unit: 'seconds')
182
+ @previous_metrics[max_name] = elapsed
183
+ end
184
+ end
161
185
  end
162
186
 
163
187
  def reduce_minute
164
- metric(MINUTE_METRIC) do
165
- ReducerModel
166
- .all_files(type: :DECOM, target: @target_name, scope: @scope)
167
- .each do |file|
168
- process_file(file, 'minute', MINUTE_ENTRY_NSECS, MINUTE_FILE_NSECS)
169
- ReducerModel.rm_file(file)
188
+ @mutex.synchronize do
189
+ metric(MINUTE_METRIC) do
190
+ processed = false
191
+ ReducerModel
192
+ .all_files(type: :DECOM, target: @target_name, scope: @scope)
193
+ .each do |file|
194
+ process_file(file, 'minute', MINUTE_ENTRY_NSECS, MINUTE_FILE_NSECS)
195
+ ReducerModel.rm_file(file)
196
+ processed = true
170
197
  end
198
+ processed # return to yield
199
+ end
171
200
  end
172
201
  end
173
202
 
174
203
  def reduce_hour
175
- metric(HOUR_METRIC) do
176
- ReducerModel
177
- .all_files(type: :MINUTE, target: @target_name, scope: @scope)
178
- .each do |file|
179
- process_file(file, 'hour', HOUR_ENTRY_NSECS, HOUR_FILE_NSECS)
180
- ReducerModel.rm_file(file)
204
+ @mutex.synchronize do
205
+ metric(HOUR_METRIC) do
206
+ processed = false
207
+ ReducerModel
208
+ .all_files(type: :MINUTE, target: @target_name, scope: @scope)
209
+ .each do |file|
210
+ process_file(file, 'hour', HOUR_ENTRY_NSECS, HOUR_FILE_NSECS)
211
+ ReducerModel.rm_file(file)
212
+ processed = true
181
213
  end
214
+ processed # return to yield
215
+ end
182
216
  end
183
217
  end
184
218
 
185
219
  def reduce_day
186
- metric(DAY_METRIC) do
187
- ReducerModel
188
- .all_files(type: :HOUR, target: @target_name, scope: @scope)
189
- .each do |file|
190
- process_file(file, 'day', DAY_ENTRY_NSECS, DAY_FILE_NSECS)
191
- ReducerModel.rm_file(file)
220
+ @mutex.synchronize do
221
+ metric(DAY_METRIC) do
222
+ processed = false
223
+ ReducerModel
224
+ .all_files(type: :HOUR, target: @target_name, scope: @scope)
225
+ .each do |file|
226
+ process_file(file, 'day', DAY_ENTRY_NSECS, DAY_FILE_NSECS)
227
+ ReducerModel.rm_file(file)
228
+ processed = true
192
229
  end
230
+ processed # return to yield
231
+ end
193
232
  end
194
233
  end
195
234
 
@@ -197,8 +236,12 @@ module OpenC3
197
236
  throttle = OpenC3::Throttle.new(@max_cpu_utilization)
198
237
  file = BucketFile.new(filename)
199
238
  file.retrieve
200
- unless file.local_path
201
- @logger.warn("Reducer Warning: #{filename}: Could not be retrieved")
239
+ unless File.exist?(file.local_path)
240
+ @logger.warn("Reducer Warning: #{file.local_path}: Does not exist")
241
+ return
242
+ end
243
+ unless File.size(file.local_path) > 0
244
+ @logger.warn("Reducer Warning: #{file.local_path}: Is zero bytes")
202
245
  return
203
246
  end
204
247
  throttle.throttle_sleep
@@ -270,17 +313,38 @@ module OpenC3
270
313
  @logger.debug("Reducer Throttle: #{filename}: total_time: #{Time.now - throttle.reset_time}, sleep_time: #{throttle.total_sleep_time}")
271
314
 
272
315
  @count += 1
273
- @metric.set(name: 'reducer_total', value: @count, type: 'counter')
316
+ if type == 'minute'
317
+ metric_name = 'reducer_minute_total'
318
+ elsif type == 'hour'
319
+ metric_name = 'reducer_hour_total'
320
+ else
321
+ metric_name = 'reducer_day_total'
322
+ end
323
+ @previous_metrics[metric_name] ||= 0
324
+ @previous_metrics[metric_name] += 1
325
+ @metric.set(name: metric_name, value: @previous_metrics[metric_name], type: 'counter')
274
326
 
275
327
  true
276
328
  rescue => e
277
329
  if file.local_path and File.exist?(file.local_path)
278
- @logger.error("Reducer Error: #{filename}: #{File.size(file.local_path)} bytes: \n#{e.formatted}")
330
+ @logger.error("Reducer Error: #{file.local_path}: #{File.size(file.local_path)} bytes: \n#{e.formatted}")
279
331
  else
280
332
  @logger.error("Reducer Error: #{filename}: \n#{e.formatted}")
281
333
  end
334
+
282
335
  @error_count += 1
283
- @metric.set(name: 'reducer_error_total', value: @error_count, type: 'counter')
336
+ if type == 'minute'
337
+ metric_name = 'reducer_minute_error_total'
338
+ elsif type == 'hour'
339
+ metric_name = 'reducer_hour_error_total'
340
+ else
341
+ metric_name = 'reducer_day_error_total'
342
+ end
343
+ @previous_metrics[metric_name] ||= 0
344
+ @previous_metrics[metric_name] += 1
345
+ @metric.set(name: metric_name, value: @previous_metrics[metric_name], type: 'counter')
346
+
347
+ file.delete
284
348
  false
285
349
  end
286
350
 
@@ -26,13 +26,10 @@ require 'openc3/utilities/store'
26
26
  module OpenC3
27
27
  class AuthModel
28
28
  PRIMARY_KEY = 'OPENC3__TOKEN'
29
- SERVICE_KEY = 'OPENC3__SERVICE__TOKEN'
30
29
 
31
30
  TOKEN_CACHE_TIMEOUT = 5
32
31
  @@token_cache = nil
33
32
  @@token_cache_time = nil
34
- @@service_token_cache = nil
35
- @@service_token_cache_time = nil
36
33
 
37
34
  def self.is_set?(key = PRIMARY_KEY)
38
35
  Store.exists(key) == 1
@@ -43,20 +40,15 @@ module OpenC3
43
40
 
44
41
  token_hash = hash(token)
45
42
  return true if @@token_cache and (Time.now - @@token_cache_time) < TOKEN_CACHE_TIMEOUT and @@token_cache == token_hash
46
- return true if @@service_token_cache and (Time.now - @@service_token_cache_time) < TOKEN_CACHE_TIMEOUT and @@service_token_cache == token_hash and permission != 'admin'
47
43
 
48
44
  @@token_cache = Store.get(PRIMARY_KEY)
49
45
  @@token_cache_time = Time.now
50
46
  return true if @@token_cache == token_hash
51
47
 
52
- @@service_token_cache = Store.get(SERVICE_KEY)
53
- @@service_token_cache_time = @@token_cache_time
54
- if ENV['OPENC3_SERVICE_PASSWORD'] and hash(ENV['OPENC3_SERVICE_PASSWORD']) != @@service_token_cache
55
- set_hash = hash(ENV['OPENC3_SERVICE_PASSWORD'])
56
- OpenC3::Store.set(SERVICE_KEY, set_hash)
57
- @@service_token_cache = set_hash
58
- end
59
- return true if @@service_token_cache == token_hash and permission != 'admin'
48
+ # Handle a service password - Generally only used by ScriptRunner
49
+ service_password = ENV['OPENC3_SERVICE_PASSWORD']
50
+ return true if service_password and service_password == token and permission != 'admin'
51
+
60
52
  return false
61
53
  end
62
54
 
@@ -926,6 +926,7 @@ module OpenC3
926
926
  work_dir: '/openc3/lib/openc3/microservices',
927
927
  options: [
928
928
  ["MAX_CPU_UTILIZATION", @reducer_max_cpu_utilization],
929
+ ["BUFFER_DEPTH", @tlm_buffer_depth]
929
930
  ],
930
931
  topics: topics,
931
932
  plugin: @plugin,
@@ -222,7 +222,7 @@ module OpenC3
222
222
  # generate the auth object
223
223
  def generate_auth
224
224
  if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
225
- if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
225
+ if ENV['OPENC3_API_PASSWORD']
226
226
  return OpenC3Authentication.new()
227
227
  else
228
228
  return nil
@@ -260,7 +260,7 @@ module OpenC3
260
260
  disconnect = kw_params.delete(:disconnect)
261
261
  # The only commands allowed through in disconnect mode are read-only
262
262
  # Thus we allow the get, list, tlm and limits_enabled and subscribe methods
263
- if method_name =~ /get_\w*|list_\w*|^tlm|limits_enabled|subscribe/
263
+ if method_name =~ /\w*_get$|^get_\w*|\w*_list$|^list_\w*|^tlm|^limits_enabled$|^subscribe$/
264
264
  result = @json_drb.method_missing(method_name, *method_params, **kw_params)
265
265
  end
266
266
  # If they overrode the return value using the disconnect keyword then return that
@@ -292,7 +292,7 @@ module OpenC3
292
292
  # generate the auth object
293
293
  def generate_auth
294
294
  if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
295
- if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
295
+ if ENV['OPENC3_API_PASSWORD']
296
296
  return OpenC3Authentication.new()
297
297
  else
298
298
  return nil
@@ -161,7 +161,7 @@ module OpenC3
161
161
  # Generate the appropriate token for OpenC3
162
162
  def generate_auth
163
163
  if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
164
- if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
164
+ if ENV['OPENC3_API_PASSWORD']
165
165
  return OpenC3Authentication.new()
166
166
  else
167
167
  raise "Environment Variables Not Set for Authentication"
@@ -31,9 +31,9 @@ module OpenC3
31
31
  # OpenC3 base / open source authentication code
32
32
  class OpenC3Authentication
33
33
  def initialize()
34
- @token = ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
34
+ @token = ENV['OPENC3_API_PASSWORD']
35
35
  if @token.nil?
36
- raise OpenC3AuthenticationError, "Authentication requires environment variables OPENC3_API_PASSWORD or OPENC3_SERVICE_PASSWORD"
36
+ raise OpenC3AuthenticationError, "Authentication requires environment variable OPENC3_API_PASSWORD"
37
37
  end
38
38
  end
39
39
 
@@ -68,12 +68,30 @@ class BucketFile
68
68
  @topic_prefix = "#{scope}__#{type}__{#{target_name}}"
69
69
  end
70
70
 
71
+ # Returns true if the file was retrieved and added to the disk
72
+ # Returns false if the file already exists
73
+ # Raises an error on retrieval errors
71
74
  def retrieve(client = @bucket, uncompress = true)
72
75
  @mutex.synchronize do
73
76
  local_path = "#{BucketFileCache.instance.cache_dir}/#{File.basename(@bucket_path)}"
74
77
  unless File.exist?(local_path)
75
78
  OpenC3::Logger.debug "Retrieving #{@bucket_path} from logs bucket"
76
- client.get_object(bucket: ENV['OPENC3_LOGS_BUCKET'], key: @bucket_path, path: local_path)
79
+
80
+ retry_count = 0
81
+ begin
82
+ client_result = client.get_object(bucket: ENV['OPENC3_LOGS_BUCKET'], key: @bucket_path, path: local_path)
83
+ unless File.exist?(local_path)
84
+ raise "Local file does not exist after get_object: #{client_result.inspect}"
85
+ end
86
+ rescue => err
87
+ # Try to retrieve the file three times
88
+ retry_count += 1
89
+ raise err if retry_count >= 3
90
+ Logger.warn("Error retrieving log file from bucket - retry #{retry_count}: #{@bucket_path}\n#{err.formatted}")
91
+ sleep(1)
92
+ retry
93
+ end
94
+
77
95
  if File.exist?(local_path)
78
96
  basename = File.basename(local_path)
79
97
  if uncompress and File.extname(basename) == ".gz"
@@ -1,14 +1,14 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- OPENC3_VERSION = '5.11.0'
3
+ OPENC3_VERSION = '5.11.1'
4
4
  module OpenC3
5
5
  module Version
6
6
  MAJOR = '5'
7
7
  MINOR = '11'
8
- PATCH = '0'
8
+ PATCH = '1'
9
9
  OTHER = ''
10
- BUILD = 'f994eee0c2fadfc67ffbf0865ba798ed11ec1f5c'
10
+ BUILD = 'b87f91f54de92aa77746d8be150f85d2f3ceeec8'
11
11
  end
12
- VERSION = '5.11.0'
13
- GEM_VERSION = '5.11.0'
12
+ VERSION = '5.11.1'
13
+ GEM_VERSION = '5.11.1'
14
14
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "5.11.0",
3
+ "version": "5.11.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.11.0",
15
+ "@openc3/tool-common": "5.11.1",
16
16
  "@angular/animations": "^16.2.4",
17
17
  "@angular/cdk": "^16.2.3",
18
18
  "@angular/common": "^16.2.4",
@@ -5,4 +5,4 @@ export const singleSpaPropsSubject = new ReplaySubject<SingleSpaProps>(1);
5
5
 
6
6
  // Add any custom single-spa props you have to this type def
7
7
  // https://single-spa.js.org/docs/building-applications.html#custom-props
8
- export type SingleSpaProps = AppProps & {};
8
+ export type SingleSpaProps = AppProps; // & {};
@@ -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.11.0",
14
+ "@openc3/tool-common": "5.11.1",
15
15
  "@smui/button": "^7.0.0-beta.15",
16
16
  "@smui/card": "^7.0.0-beta.15",
17
17
  "@smui/list": "^7.0.0-beta.15",
@@ -58,7 +58,7 @@ export class ConfigParserService {
58
58
  }
59
59
  }
60
60
  // If they pass null for max_params we don't check for a maximum number
61
- if (max_num_params && !this.parameters[max_num_params] === undefined) {
61
+ if (max_num_params && this.parameters[max_num_params] !== undefined) {
62
62
  throw new ConfigParserError(
63
63
  this,
64
64
  `Too many parameters for ${this.keyword}.`,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "5.11.0",
3
+ "version": "5.11.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.11.0",
14
+ "@openc3/tool-common": "5.11.1",
15
15
  "axios": "0.27.2",
16
16
  "date-fns": "2.30.0",
17
17
  "portal-vue": "2.1.7",
@@ -1,4 +1,4 @@
1
- const path = require("path");
1
+ const path = require('path')
2
2
 
3
3
  module.exports = {
4
4
  publicPath: '/tools/<%= tool_name %>',
@@ -20,11 +20,19 @@ module.exports = {
20
20
  },
21
21
  configureWebpack: {
22
22
  output: {
23
- libraryTarget: 'system'
23
+ libraryTarget: 'system',
24
24
  },
25
25
  },
26
26
  chainWebpack: (config) => {
27
27
  config.module.rule('js').use('babel-loader')
28
+ config.module
29
+ .rule('vue')
30
+ .use('vue-loader')
31
+ .tap((options) => {
32
+ return {
33
+ prettify: false,
34
+ }
35
+ })
28
36
  config.externals(['vue', 'vuetify', 'vuex', 'vue-router'])
29
37
  },
30
38
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "widget",
3
- "version": "5.11.0",
3
+ "version": "5.11.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.11.0",
9
+ "@openc3/tool-common": "5.11.1",
10
10
  "vue": "2.7.14",
11
11
  "vuetify": "2.7.1"
12
12
  },
@@ -15,11 +15,14 @@ module.exports = {
15
15
  rootMode: 'upward',
16
16
  }
17
17
  })
18
- config.externals([
19
- 'vue',
20
- 'vuetify',
21
- 'vuex',
22
- 'vue-router',
23
- ])
18
+ config.module
19
+ .rule('vue')
20
+ .use('vue-loader')
21
+ .tap((options) => {
22
+ return {
23
+ prettify: false,
24
+ }
25
+ })
26
+ config.externals(['vue', 'vuetify', 'vuex', 'vue-router'])
24
27
  },
25
28
  }
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.11.0
4
+ version: 5.11.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: 2023-09-18 00:00:00.000000000 Z
12
+ date: 2023-09-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler