class Rundoc::CodeCommand::Background::ProcessSpawn
This class is responsible for running processes in the background
By default it logs output to a file. This can be used to “wait” for a specific output before continuing:
server = ProcessSpawn("rails server") server.wait("Use Ctrl-C to stop")
The process can be queried for it's status to check if it is still booted or not. the process can also be manually stopped:
server = ProcessSpawn("rails server") server.alive? # => true server.stop server.alive? # => false
There are class level methods that can be used to “name” and record background processes. They can be used like this:
server = ProcessSpawn("rails server") ProcessSpawn.add("muh_server", server) ProcessSpawn.find("muh_server") # => <# ProcessSpawn instance > ProcessSpawn.find("foo") # => RuntimeError "Could not find task with name 'foo', ..."
Attributes
log[R]
pid[R]
Public Class Methods
add(name, value)
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 36 def self.add(name, value) raise "Task named #{name.inspect} is already started, choose a different name" if @tasks[name] @tasks[name] = value end
find(name)
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 41 def self.find(name) raise "Could not find task with name #{name.inspect}, known task names: #{@tasks.keys.inspect}" unless @tasks[name] @tasks[name] end
new(command , timeout: 5, log: Tempfile.new("log"), out: "2>&1")
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 48 def initialize(command , timeout: 5, log: Tempfile.new("log"), out: "2>&1") @command = command @timeout_value = timeout @log_reference = log # https://twitter.com/schneems/status/1285289971083907075 @log = Pathname.new(log) @log.dirname.mkpath FileUtils.touch(@log) @command = "/usr/bin/env bash -c #{@command.shellescape} >> #{@log} #{out}" @pid = nil end
tasks()
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 31 def self.tasks @tasks end
Public Instance Methods
alive?()
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 75 def alive? return false unless @pid Process.kill(0, @pid) rescue Errno::ESRCH, Errno::EPERM false end
check_alive!()
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 88 def check_alive! raise "#{@original_command} has exited unexpectedly: #{@log.read}" unless alive? end
stop()
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 82 def stop return unless alive? Process.kill('TERM', -Process.getpgid(@pid)) Process.wait(@pid) end
wait(wait_value = nil, timeout_value = @timeout_value)
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 61 def wait(wait_value = nil, timeout_value = @timeout_value) call return unless wait_value Timeout.timeout(Integer(timeout_value)) do until @log.read.match(wait_value) sleep 0.01 end end rescue Timeout::Error raise "Timeout waiting for #{@command.inspect} to find a match using #{ wait_value.inspect } in \n'#{ log.read }'" false end
Private Instance Methods
call()
click to toggle source
# File lib/rundoc/code_command/background/process_spawn.rb, line 92 def call @pid ||= Process.spawn(@command, pgroup: true) end