class NodeTask
Constants
- RESPONSE_TIMEOUT
- START_MAX_RETRIES
Attributes
logger[W]
node_command[W]
working_dir[W]
task[RW]
Public Class Methods
alive?()
click to toggle source
# File lib/node_task/node_task.rb, line 163 def alive? current_pid = nil alive = false if @controller begin current_pid = @controller.pid rescue Errno::ENOENT end end if current_pid begin Process.getpgid(current_pid) alive = true rescue Errno::ESRCH end end alive end
check_error()
click to toggle source
# File lib/node_task/node_task.rb, line 117 def check_error if File.exist? error_log_file # TODO: raise error logger.error File.open(error_log_file).read File.unlink error_log_file true end end
daemon_env()
click to toggle source
# File lib/node_task/node_task.rb, line 196 def daemon_env { "NODE_TASK_SOCK_PATH" => socket_path, "NODE_TASK_CWD" => working_dir, "NODE_TASK_DAEMON_ID" => daemon_identifier, "NODE_TASK_PARENT_PID" => Process.pid.to_s, "NODE_TASK_PARENT_CHECK_INTERVAL" => parent_check_interval.to_s, "NODE_ENV" => ENV["RACK_ENV"], } end
daemon_identifier()
click to toggle source
# File lib/node_task/node_task.rb, line 59 def daemon_identifier 'ruby_node_task' end
daemon_start_script()
click to toggle source
# File lib/node_task/node_task.rb, line 71 def daemon_start_script File.join(gem_dir, 'nodeTask.js').to_s end
ensure_connection()
click to toggle source
really try to successfully connect, starting the daemon if required
# File lib/node_task/node_task.rb, line 90 def ensure_connection attempt = 0 begin server # make sure daemon is running socket = server.connect do begin _make_connection rescue Errno::ENOENT => e # daemon_controller doesn't understand ENOENT raise Errno::ECONNREFUSED, e.message end end rescue DaemonController::StartTimeout, DaemonController::StartError => e logger.error e.message if attempt < START_MAX_RETRIES attempt += 1 logger.error "retrying attempt #{attempt}" retry else raise e end end socket end
error_log_file()
click to toggle source
# File lib/node_task/node_task.rb, line 47 def error_log_file File.join(working_dir, "#{daemon_identifier}-error.log") end
gem_dir()
click to toggle source
# File lib/node_task/node_task.rb, line 55 def gem_dir @gem_dir ||= File.dirname(File.expand_path(__FILE__)) end
logger()
click to toggle source
# File lib/node_task/node_task.rb, line 36 def logger return @logger unless @logger.nil? @logger = Logger.new(STDERR) @logger.level = ENV["NODE_TASK_DEBUG"] ? Logger::DEBUG : Logger::INFO @logger end
new(_task)
click to toggle source
# File lib/node_task/node_task.rb, line 256 def initialize(_task) @task = _task end
node_command()
click to toggle source
# File lib/node_task/node_task.rb, line 67 def node_command @node_command || ENV["NODE_COMMAND"] || 'node' end
parent_check_interval()
click to toggle source
# File lib/node_task/node_task.rb, line 207 def parent_check_interval 1000 end
parse_response(socket)
click to toggle source
get a json response from socket
# File lib/node_task/node_task.rb, line 127 def parse_response(socket) # only take one message - the result # response terminated by newline response_text = nil loop do response_text = socket.gets("\n") break if response_text break if check_error end if response_text JSON.parse(response_text, symbolize_names: true) else logger.error 'no response for message' nil end end
pid_file()
click to toggle source
# File lib/node_task/node_task.rb, line 51 def pid_file File.join(working_dir, "#{daemon_identifier}.pid") end
release()
click to toggle source
stop the daemon
# File lib/node_task/node_task.rb, line 183 def release return unless alive? logger.debug "stopping daemon #{@controller.pid}" @controller.stop begin File.unlink socket_path rescue Errno::ENOENT => e # socket file's already gone end end
request(socket, message)
click to toggle source
make a single request, get a response and close the connection
# File lib/node_task/node_task.rb, line 145 def request(socket, message) socket.write(message.to_json+"\n") result = nil begin Timeout::timeout(RESPONSE_TIMEOUT) do result = parse_response(socket) end rescue Timeout::Error, Exception => e logger.error e.message ensure # disconnect after receiving response socket.close end result end
server()
click to toggle source
get configured daemon controller for daemon, and start it
# File lib/node_task/node_task.rb, line 76 def server @controller ||= _make_daemon_controller begin @controller.start logger.debug "spawned server #{@controller.pid}" rescue DaemonController::AlreadyStarted => e logger.debug "server already running #{@controller.pid}" end @controller end
socket_path()
click to toggle source
# File lib/node_task/node_task.rb, line 63 def socket_path @socket_path ||= _make_sock_path(working_dir, daemon_identifier) end
windows?()
click to toggle source
# File lib/node_task/node_task.rb, line 32 def windows? (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil end
working_dir()
click to toggle source
# File lib/node_task/node_task.rb, line 43 def working_dir @working_dir || Dir.pwd end
Private Class Methods
_make_connection()
click to toggle source
# File lib/node_task/node_task.rb, line 213 def _make_connection UNIXSocket.new socket_path end
_make_daemon_controller()
click to toggle source
TODO:
-
some server errors not reported
# File lib/node_task/node_task.rb, line 227 def _make_daemon_controller logger.debug "socket_path #{socket_path}" logger.debug "starting #{node_command} #{daemon_start_script}" controller = DaemonController.new( identifier: daemon_identifier, start_command: "#{node_command} #{daemon_start_script}", ping_command: Proc.new{ begin _make_connection rescue Errno::ENOENT => e # daemon_controller doesn't understand ENOENT raise Errno::ECONNREFUSED, e.message end }, pid_file: pid_file, log_file: error_log_file, env: daemon_env, log_file_activity_timeout: RESPONSE_TIMEOUT, start_timeout: RESPONSE_TIMEOUT, daemonize_for_me: true, ) controller end
_make_sock_path(dir, name)
click to toggle source
# File lib/node_task/node_task.rb, line 217 def _make_sock_path(dir, name) if windows? "\\\\.\\pipe\\#{name}\\#{File.expand_path(dir)}" else File.join(dir, "#{name}.sock") end end
Public Instance Methods
run(opts = nil)
click to toggle source
# File lib/node_task/node_task.rb, line 260 def run(opts = nil) socket = self.class.ensure_connection message = { task: task, opts: opts, } response = self.class.request(socket, message) if response if response[:error] raise NodeTask::Error, response[:error] else response[:result] end end end