class Schmooze::Base
Public Class Methods
new(root, env={})
click to toggle source
# File lib/schmooze/base.rb, line 43 def initialize(root, env={}) @_schmooze_env = env @_schmooze_root = root @_schmooze_code = ProcessorGenerator.generate(self.class.instance_variable_get(:@_schmooze_imports) || [], self.class.instance_variable_get(:@_schmooze_methods) || []) end
Protected Class Methods
dependencies(deps)
click to toggle source
# File lib/schmooze/base.rb, line 10 def dependencies(deps) @_schmooze_imports ||= [] deps.each do |identifier, package| @_schmooze_imports << { identifier: identifier, package: package } end end
finalize(stdin, stdout, stderr, process_thread)
click to toggle source
# File lib/schmooze/base.rb, line 32 def finalize(stdin, stdout, stderr, process_thread) proc do stdin.close stdout.close stderr.close Process.kill(0, process_thread.pid) process_thread.value end end
method(name, code)
click to toggle source
# File lib/schmooze/base.rb, line 20 def method(name, code) @_schmooze_methods ||= [] @_schmooze_methods << { name: name, code: code } define_method(name) do |*args| call_js_method(name, args) end end
Public Instance Methods
pid()
click to toggle source
# File lib/schmooze/base.rb, line 49 def pid @_schmooze_process_thread && @_schmooze_process_thread.pid end
Private Instance Methods
call_js_method(method, args)
click to toggle source
# File lib/schmooze/base.rb, line 102 def call_js_method(method, args) ensure_process_is_spawned @_schmooze_stdin.puts JSON.dump([method, args]) input = @_schmooze_stdout.gets raise Errno::EPIPE, "Can't read from stdout" if input.nil? status, message, error_class = JSON.parse(input) if status == 'ok' message else if error_class.nil? raise Schmooze::JavaScript::UnknownError, message else raise Schmooze::JavaScript.const_get(error_class, false), message end end rescue Errno::EPIPE, IOError # TODO(bouk): restart or something? If this happens the process is completely broken raise ::StandardError, "Schmooze process failed:\n#{@_schmooze_stderr.read}" end
ensure_packages_are_initiated(stdin, stdout, stderr, process_thread)
click to toggle source
# File lib/schmooze/base.rb, line 72 def ensure_packages_are_initiated(stdin, stdout, stderr, process_thread) input = stdout.gets raise Schmooze::Error, "Failed to instantiate Schmooze process:\n#{stderr.read}" if input.nil? result = JSON.parse(input) unless result[0] == 'ok' stdin.close stdout.close stderr.close process_thread.join error_message = result[1] if /\AError: Cannot find module '(.*)'\z/ =~ error_message package_name = $1 package_json_path = File.join(@_schmooze_root, 'package.json') begin package = JSON.parse(File.read(package_json_path)) %w(dependencies devDependencies).each do |key| if package.has_key?(key) && package[key].has_key?(package_name) raise Schmooze::DependencyError, "Cannot find module '#{package_name}'. The module was found in '#{package_json_path}' however, please run 'npm install' from '#{@_schmooze_root}'" end end rescue Errno::ENOENT end raise Schmooze::DependencyError, "Cannot find module '#{package_name}'. You need to add it to '#{package_json_path}' and run 'npm install'" else raise Schmooze::Error, error_message end end end
ensure_process_is_spawned()
click to toggle source
# File lib/schmooze/base.rb, line 54 def ensure_process_is_spawned return if @_schmooze_process_thread spawn_process end
spawn_process()
click to toggle source
# File lib/schmooze/base.rb, line 59 def spawn_process process_data = Open3.popen3( @_schmooze_env, 'node', '-e', @_schmooze_code, chdir: @_schmooze_root ) ensure_packages_are_initiated(*process_data) ObjectSpace.define_finalizer(self, self.class.send(:finalize, *process_data)) @_schmooze_stdin, @_schmooze_stdout, @_schmooze_stderr, @_schmooze_process_thread = process_data end