class SProc::SProc::TaskRunner

Helper class that runs one task using the preconditions given at instantiation. This class is not intended for external use

Constants

DEFAULT_OPTS
SUPPORTED_SPAWN_OPTS

Restrict the options to Process.spawn that we support to these

Attributes

task_info[R]

Public Class Methods

new(opts) click to toggle source
# File lib/sproc/core.rb, line 263
def initialize(opts)
  @task_info = TaskInfo.new('', nil, 0, nil, nil, String.new, String.new)
  @opts = DEFAULT_OPTS.dup.merge!(opts)
end

Public Instance Methods

execute(env, cmd, *args, **opts) click to toggle source

Runs the process and blocks until it is completed or aborted. The stdout and stdin streams are continuously read in parallel with the process execution.

# File lib/sproc/core.rb, line 271
def execute(env, cmd, *args, **opts)
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  begin
    shell_out_via_popen(env, cmd, *args, **opts)
  rescue StandardError => e
    @task_info[:exception] = e
  end
  @task_info[:wall_time] = (Process.clock_gettime(
    Process::CLOCK_MONOTONIC
  ) - start_time)
end

Private Instance Methods

do_while_process_running(_stdin, stdout, stderr) click to toggle source
# File lib/sproc/core.rb, line 325
def do_while_process_running(_stdin, stdout, stderr)
  th1 = process_output_stream(stdout,
                              @task_info[:stdout], @opts[:stdout_callback])
  th2 = process_output_stream(stderr,
                              @task_info[:stderr], @opts[:stderr_callback])
  [th1, th2]
end
get_args_bash(cmd, *args, **opts) click to toggle source

convert arguments to a string prepended with bash -c

# File lib/sproc/core.rb, line 319
def get_args_bash(cmd, *args, **opts)
  cmd_str = ([cmd] + args).each { |a| Shellwords.escape(a) }.join(' ')
  @task_info[:cmd_str] = "bash -c \"#{cmd_str}\""
  [@task_info[:cmd_str], opts]
end
get_args_native(cmd, *args, **opts) click to toggle source
# File lib/sproc/core.rb, line 312
def get_args_native(cmd, *args, **opts)
  cmd_args = args.flatten.map(&:to_s)
  @task_info[:cmd_str] = "#{cmd} #{cmd_args.join(' ')}"
  [cmd.to_s, *cmd_args, opts]
end
process_output_stream(stream, stream_cache = nil, process_callback = nil) click to toggle source

process an output stream within a separate thread

# File lib/sproc/core.rb, line 334
def process_output_stream(stream, stream_cache = nil,
                          process_callback = nil)
  Thread.new do
    until (raw_line = stream.gets).nil?
      process_callback&.call(raw_line)
      # log stream output directly in debug mode
      SProc.logger&.debug { raw_line }
      stream_cache << raw_line unless stream_cache.nil?
    end
  rescue IOError => e
    l = SProc.logger
    l&.warn { 'Stream closed before all output were read!' }
    l&.warn { e.message }
  end
end
shell_out_via_popen(env, cmd, *args, **opts) click to toggle source
# File lib/sproc/core.rb, line 293
def shell_out_via_popen(env, cmd, *args, **opts)
  opts = valid_opts(**opts)
  args = case @opts[:type]
         when NONE then get_args_native(cmd, *args, **opts)
         when BASH then get_args_bash(cmd, *args, **opts)
         else raise ArgumentError, "Unknown task type: #{@type}!!"
         end

  SProc.logger&.debug { "Start: #{task_info[:cmd_str]}" }
  SProc.logger&.debug { "Supplying env: #{env}" } unless env.nil?
  SProc.logger&.debug { "Spawn options: #{opts}" } unless opts.nil?
  Open3.popen3(env, *args) do |stdin, stdout, stderr, thread|
    @task_info[:popen_thread] = thread
    threads = do_while_process_running(stdin, stdout, stderr)
    @task_info[:process_status] = thread.value
    threads.each(&:join)
  end
end
valid_opts(**opts) click to toggle source
# File lib/sproc/core.rb, line 285
def valid_opts(**opts)
  return opts if opts.nil? || opts.empty?

  supported = {}
  SUPPORTED_SPAWN_OPTS.each { |o| supported[o] = opts[o] if opts.has_key?(o) }
  supported
end