From 4f1a7cde27a69a94d95cb66bcee2061e8d772b21 Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Sat, 30 Oct 2021 01:12:16 +0200 Subject: [PATCH] Add null strategy for runners * This is the default strategy used when the runner management is disabled. It might be replaced with a generic Docker strategy in the future (without pooling). For now, it allows normal "operation" of CodeOcean without any runner management. However, as no runner system is configured, no command can be executed. --- app/models/runner.rb | 10 ++++--- lib/runner/strategy/null.rb | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 lib/runner/strategy/null.rb diff --git a/app/models/runner.rb b/app/models/runner.rb index 4931db8e..21af9d96 100644 --- a/app/models/runner.rb +++ b/app/models/runner.rb @@ -11,10 +11,12 @@ class Runner < ApplicationRecord attr_accessor :strategy def self.strategy_class - @strategy_class ||= begin - strategy_name = CodeOcean::Config.new(:code_ocean).read[:runner_management][:strategy] - "runner/strategy/#{strategy_name}".camelize.constantize - end + @strategy_class ||= if Runner.management_active? + strategy_name = CodeOcean::Config.new(:code_ocean).read[:runner_management][:strategy] + "runner/strategy/#{strategy_name}".camelize.constantize + else + Runner::Strategy::Null + end end def self.management_active? diff --git a/lib/runner/strategy/null.rb b/lib/runner/strategy/null.rb new file mode 100644 index 00000000..38ff522f --- /dev/null +++ b/lib/runner/strategy/null.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +# This strategy allows normal operation of CodeOcean even when the runner management is disabled. +# However, as no command can be executed, all execution requests will fail. +class Runner::Strategy::Null < Runner::Strategy + def self.initialize_environment; end + + def self.sync_environment(_environment); end + + def self.request_from_management(_environment) + SecureRandom.uuid + end + + def destroy_at_management; end + + def copy_files(_files); end + + def attach_to_execution(command, event_loop) + socket = Connection.new(nil, self, event_loop) + # We don't want to return an error if the execution environment is changed + socket.status = :terminated_by_codeocean if command == ExecutionEnvironment::VALIDATION_COMMAND + yield(socket) + socket + end + + def self.available_images + [] + end + + def self.config; end + + def self.release + 'N/A' + end + + def self.pool_size + {} + end + + def self.websocket_header + {} + end + + class Connection < Runner::Connection + def decode(event_data) + event_data + end + + def encode(data) + data + end + + def active? + false + end + end +end