class RemoteRuby::ExecutionContext

This class is responsible for executing blocks on the remote host with the specified adapters. This is the entrypoint to RemoteRuby logic.

Attributes

adapter_klass[R]
cache_dir[R]
err_stream[R]
flavours[R]
out_stream[R]
params[R]
save_cache[R]
use_cache[R]

Public Class Methods

new(**params) click to toggle source

rubocop:disable Metrics/CyclomaticComplexity

# File lib/remote_ruby/execution_context.rb, line 16
def initialize(**params)
  add_flavours(params)
  @use_cache = params.delete(:use_cache)   || false
  @save_cache = params.delete(:save_cache) || false
  @cache_dir = params.delete(:cache_dir)   || File.join(Dir.pwd, 'cache')
  @out_stream = params.delete(:out_stream) || $stdout
  @err_stream = params.delete(:err_stream) || $stderr
  @adapter_klass = params.delete(:adapter) || ::RemoteRuby::SSHStdinAdapter
  @params = params

  FileUtils.mkdir_p(@cache_dir)
end

Public Instance Methods

execute(locals = nil, &block) click to toggle source

rubocop:enable Metrics/CyclomaticComplexity

# File lib/remote_ruby/execution_context.rb, line 30
def execute(locals = nil, &block)
  source = code_source(block)
  locals ||= extract_locals(block)

  result = execute_code(source, **locals)

  assign_locals(locals.keys, result[:locals], block)

  result[:result]
end

Private Instance Methods

adapter(code_hash) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 105
def adapter(code_hash)
  actual_adapter = adapter_klass.new(params)

  if use_cache && cache_exists?(code_hash)
    cache_adapter(actual_adapter, code_hash)
  elsif save_cache
    caching_adapter(actual_adapter, code_hash)
  else
    actual_adapter
  end
end
add_flavours(params) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 131
def add_flavours(params)
  @flavours = ::RemoteRuby::Flavour.build_flavours(params)
end
assign_locals(local_names, values, block) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 46
def assign_locals(local_names, values, block)
  local_names.each do |local|
    next unless values.key?(local)

    block.binding.local_variable_set(local, values[local])
  end
end
cache_adapter(adapter, code_hash) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 117
def cache_adapter(adapter, code_hash)
  ::RemoteRuby::CacheAdapter.new(
    connection_name: adapter.connection_name,
    cache_path: cache_path(code_hash)
  )
end
cache_exists?(code_hash) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 79
def cache_exists?(code_hash)
  hsh = cache_path(code_hash)
  File.exist?("#{hsh}.stdout") || File.exist?("#{hsh}.stderr")
end
cache_path(code_hash) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 74
def cache_path(code_hash)
  hsh = context_hash(code_hash)
  File.join(cache_dir, hsh)
end
caching_adapter(adapter, code_hash) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 124
def caching_adapter(adapter, code_hash)
  ::RemoteRuby::CachingAdapter.new(
    adapter: adapter,
    cache_path: cache_path(code_hash)
  )
end
code_source(block) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 60
def code_source(block)
  source_extractor = ::RemoteRuby::SourceExtractor.new
  source_extractor.extract(&block)
end
compiler(ruby_code, client_locals) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 84
def compiler(ruby_code, client_locals)
  RemoteRuby::Compiler.new(
    ruby_code,
    client_locals: client_locals,
    flavours: flavours
  )
end
context_hash(code_hash) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 65
def context_hash(code_hash)
  Digest::MD5.hexdigest(
    self.class.name +
    adapter_klass.name.to_s +
    params.to_s +
    code_hash
  )
end
execute_code(ruby_code, client_locals = {}) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 92
def execute_code(ruby_code, client_locals = {})
  compiler = compiler(ruby_code, client_locals)

  runner = ::RemoteRuby::Runner.new(
    code: compiler.compiled_code,
    adapter: adapter(compiler.code_hash),
    out_stream: out_stream,
    err_stream: err_stream
  )

  runner.run
end
extract_locals(block) click to toggle source
# File lib/remote_ruby/execution_context.rb, line 54
def extract_locals(block)
  extractor =
    ::RemoteRuby::LocalsExtractor.new(block, ignore_types: self.class)
  extractor.locals
end