class Isomorfeus::Speednode::Runtime::Context

Public Class Methods

finalize(runtime, uuid) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 5
def self.finalize(runtime, uuid)
  proc { runtime.vm.delete_context(uuid) }
end
new(runtime, source = "", options = {}) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 9
def initialize(runtime, source = "", options = {})

  @runtime = runtime
  @uuid = SecureRandom.uuid
  @permissive = !!options.delete(:permissive)
  @vm = @runtime.vm
  @context = nil
  @timeout = options[:timeout] ? options[:timeout]/1000 : 600

  ObjectSpace.define_finalizer(self, self.class.finalize(@runtime, @uuid))

  filename = options.delete(:filename)
  source = File.read(filename) if filename

  begin
    source = encode(source)
  rescue
    source = source.force_encoding('UTF-8')
  end

  @permissive ? raw_createp(source, options) : raw_create(source, options)
end

Public Instance Methods

attach(func, procedure = nil, &block) click to toggle source

def options

@vm.context_options(@uuid)

end

# File lib/isomorfeus/speednode/runtime/context.rb, line 36
def attach(func, procedure = nil, &block)
  raise "#attach requires a permissive context." unless @permissive
  run_block = block_given? ? block : procedure
  Isomorfeus::Speednode::Runtime.attach_proc(@uuid, func, run_block)
  @vm.attach(@uuid, func)
end
await(source) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 43
        def await(source)
          raw_eval <<~JAVASCRIPT
            (async () => {
              global.__LastExecutionFinished = false;
              global.__LastResult = null;
              global.__LastErr = null;
              global.__LastResult = await #{source};
              global.__LastExecutionFinished = true;
            })().catch(function(err) {
              global.__LastResult = null;
              global.__LastErr = err;
              global.__LastExecutionFinished = true;
            })
          JAVASCRIPT
          await_result
        end
call(identifier, *args) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 60
def call(identifier, *args)
  raw_eval("#{identifier}.apply(this, #{::Oj.dump(args, mode: :strict)})")
end
eval(source, _options = nil) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 64
def eval(source, _options = nil)
  raw_eval(source) if /\S/ =~ source
end
exec(source, _options = nil) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 68
def exec(source, _options = nil)
  raw_exec("(function(){#{source}})()")
end
permissive?() click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 72
def permissive?
  @permissive
end
permissive_eval(source, _options = nil) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 76
def permissive_eval(source, _options = nil)
  raise "Context not permissive!" unless @permissive
  raw_eval(source) if /\S/ =~ source
end
permissive_exec(source, _options = nil) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 81
def permissive_exec(source, _options = nil)
  raise "Context not permissive!" unless @permissive
  raw_exec("(function(){#{source}})()")
end

Protected Instance Methods

await_result() click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 135
        def await_result
          start_time = Time.now
          while !execution_finished? && !timed_out?(start_time)
            sleep 0.005
          end
          result = exec <<~JAVASCRIPT
            if (global.__LastExecutionFinished === true) {
              var err = global.__LastErr;
              var result = global.__LastResult;

              global.__LastErr = null;
              global.__LastResult = null;
              global.__LastExecutionFinished = false;

              if (err) { return ['err', ['', err].join(''), err.stack]; }
              else if (typeof result === 'undefined' && result !== null) { return ['ok']; }
              else {
                  try { return ['ok', result]; }
                  catch (err) { return ['err', ['', err].join(''), err.stack]; }
              }
            } else {
              var new_err = new Error('Last command did not yet finish execution!');
              return ['err', ['', new_err].join(''), new_err.stack];
            }
          JAVASCRIPT
          extract_result(result)
        end
execution_finished?() click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 163
def execution_finished?
  eval 'global.__LastExecutionFinished'
end
extract_result(output) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 113
def extract_result(output) 
  if output[0] == 'ok'
    output[1]
  else
    _status, value, stack = output
    stack ||= ""
    stack = stack.split("\n").map do |line|
      line.sub(" at ", "").strip
    end
    stack.reject! do |line|
      line.include?('(node:') ||
      line.include?('lib\isomorfeus\speednode\runner.js') ||
      line.include?('lib/isomorfeus/speednode/runner.js')
    end
    stack.shift unless stack[0].to_s.include?("(execjs)")
    error_class = value =~ /SyntaxError:/ ? ExecJS::RuntimeError : ExecJS::ProgramError
    error = error_class.new(value)
    error.set_backtrace(stack + caller)
    raise error
  end
end
raw_create(source, options) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 97
def raw_create(source, options)
  return if @context
  source = encode(source)
  result = @vm.create(@uuid, source, options)
  @context = true
  extract_result(result)
end
raw_createp(source, options) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 105
def raw_createp(source, options)
  return if @context
  source = encode(source)
  result = @vm.createp(@uuid, source, options)
  @context = true
  extract_result(result)
end
raw_eval(source) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 88
def raw_eval(source)
  extract_result(@vm.eval(@uuid, encode(source)))
end
raw_exec(source) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 93
def raw_exec(source)
  extract_result(@vm.exec(@uuid, encode(source)))
end
timed_out?(start_time) click to toggle source
# File lib/isomorfeus/speednode/runtime/context.rb, line 167
def timed_out?(start_time)
  if (Time.now - start_time) > @timeout
    raise "Command Execution timed out!"
  end
  false
end