Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bucket load #680

Merged
merged 3 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 6 additions & 62 deletions openc3-cosmos-script-runner-api/app/models/running_script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
require 'openc3/utilities/store'
require 'openc3/models/offline_access_model'
require 'openc3/models/environment_model'
require 'openc3/utilities/bucket_require'

RAILS_ROOT = File.expand_path(File.join(__dir__, '..', '..'))

Expand Down Expand Up @@ -85,67 +86,6 @@ def run_mode
end

OpenC3.disable_warnings do
def bucket_load(*args, **kw_args)
path = args[0]

# Only support TARGET files
if path[0] == '/' or path.split('/')[0].to_s.upcase != path.split('/')[0]
raise LoadError
end
extension = File.extname(path)
path = path + '.rb' if extension == ""

# Retrieve the text of the script from S3
scope = nil
if kw_args[:scope]
scope = kw_args[:scope]
else
if RunningScript.instance
scope = RunningScript.instance.scope
else
scope = $openc3_scope
end
end
text = ::Script.body(scope, path)

# Execute the script directly without instrumentation because we are doing require/load
Object.class_eval(text, path, 1)

# Successful load/require returns true
true
end

def require(*args, **kw_args)
begin
return super(*args, **kw_args)
rescue LoadError
begin
@bucket_require_cache ||= {}
if @bucket_require_cache[args[0]]
return false
else
bucket_load(*args, **kw_args)
@bucket_require_cache[args[0]] = true
return true
end
rescue Exception
raise LoadError
end
end
end

def load(*args, **kw_args)
begin
super(*args, **kw_args)
rescue LoadError
begin
bucket_load(*args, **kw_args)
rescue Exception
raise LoadError
end
end
end

def start(procedure_name)
path = procedure_name

Expand Down Expand Up @@ -1340,7 +1280,11 @@ def handle_exception(error, fatal, filename = nil, line_number = 0)
OpenC3::Logger.error(error.message)
else
OpenC3::Logger.error(error.class.to_s.split('::')[-1] + ' : ' + error.message)
relevent_lines = error.backtrace.select { |line| !line.include?("/src/app") && !line.include?("/openc3/lib") && !line.include?("/usr/lib/ruby") }
if ENV['OPENC3_FULL_BACKTRACE']
relevent_lines = error.backtrace
else
relevent_lines = error.backtrace.select { |line| !line.include?("/src/app") && !line.include?("/openc3/lib") && !line.include?("/usr/lib/ruby") }
end
OpenC3::Logger.error(relevent_lines.join("\n\n")) unless relevent_lines.empty?
end
handle_output_io(filename, line_number)
Expand Down
65 changes: 65 additions & 0 deletions openc3/lib/openc3/utilities/bucket_require.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# encoding: ascii-8bit

# Copyright 2022 OpenC3, Inc.
# All Rights Reserved.
#
# This program is free software; you can modify and/or redistribute it
# under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation; version 3 with
# attribution addendums as found in the LICENSE.txt
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# This file may also be used under the terms of a commercial license
# if purchased from OpenC3, Inc.

require 'openc3'
require 'openc3/utilities/bucket_utilities'

OpenC3.disable_warnings do
def require(*args, **kw_args)
begin
return super(*args, **kw_args)
rescue LoadError
begin
@bucket_require_cache ||= {}
if @bucket_require_cache[args[0]]
return false
else
scope = nil
if kw_args[:scope]
scope = kw_args[:scope]
else
scope = $openc3_scope
end
OpenC3::BucketUtilities.bucket_load(*args, scope: scope)
@bucket_require_cache[args[0]] = true
return true
end
rescue Exception => err
raise LoadError, "#{err.class}:#{err.message}", err.backtrace
end
end
end

def load(*args, **kw_args)
begin
super(*args, **kw_args)
rescue LoadError
begin
scope = nil
if kw_args[:scope]
scope = kw_args[:scope]
else
scope = $openc3_scope
end
OpenC3::BucketUtilities.bucket_load(*args, scope: scope)
rescue Exception
raise LoadError, "#{err.class}:#{err.message}", err.backtrace
end
end
end
end
21 changes: 21 additions & 0 deletions openc3/lib/openc3/utilities/bucket_utilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# if purchased from OpenC3, Inc.

require 'openc3/utilities/bucket'
require 'openc3/utilities/target_file'
require 'openc3/models/reducer_model'
require 'zlib'

Expand All @@ -29,6 +30,26 @@ class BucketUtilities
FILE_TIMESTAMP_FORMAT = "%Y%m%d%H%M%S%N"
DIRECTORY_TIMESTAMP_FORMAT = "%Y%m%d"

def self.bucket_load(*args, scope: $openc3_scope)
path = args[0]

# Only support TARGET files
if path[0] == '/' or path.split('/')[0].to_s.upcase != path.split('/')[0]
raise LoadError
end
extension = File.extname(path)
path = path + '.rb' if extension == ""

# Retrieve the text of the script from S3
text = TargetFile.body(scope, path)

# Execute the script directly without instrumentation because we are doing require/load
Object.class_eval(text, path, 1)

# Successful load/require returns true
true
end

# @param bucket [String] Name of the bucket to list
# @param prefix [String] Prefix to filter all files by
# @param start_time [Time|nil] Ruby time to find files after. nil means no start (first file on).
Expand Down