Class: Rundoc::CodeCommand::Background::ProcessSpawn
- Inherits:
-
Object
- Object
- Rundoc::CodeCommand::Background::ProcessSpawn
- Defined in:
- lib/rundoc/code_command/background/process_spawn.rb
Overview
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', ..."
Class Attribute Summary collapse
-
.tasks ⇒ Object
readonly
Returns the value of attribute tasks.
Instance Attribute Summary collapse
-
#command ⇒ Object
readonly
Returns the value of attribute command.
-
#log ⇒ Object
readonly
Returns the value of attribute log.
-
#pid ⇒ Object
readonly
Returns the value of attribute pid.
Class Method Summary collapse
Instance Method Summary collapse
- #alive? ⇒ Boolean
- #check_alive! ⇒ Object
-
#initialize(command, timeout: 5, log: Tempfile.new("log"), out: "2>&1") ⇒ ProcessSpawn
constructor
A new instance of ProcessSpawn.
- #stop ⇒ Object
- #wait(wait_value = nil, timeout_value = @timeout_value) ⇒ Object
Constructor Details
#initialize(command, timeout: 5, log: Tempfile.new("log"), out: "2>&1") ⇒ ProcessSpawn
Returns a new instance of ProcessSpawn.
48 49 50 51 52 53 54 55 56 57 58 59 |
# 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 |
Class Attribute Details
.tasks ⇒ Object (readonly)
Returns the value of attribute tasks.
32 33 34 |
# File 'lib/rundoc/code_command/background/process_spawn.rb', line 32 def tasks @tasks end |
Instance Attribute Details
#command ⇒ Object (readonly)
Returns the value of attribute command.
46 47 48 |
# File 'lib/rundoc/code_command/background/process_spawn.rb', line 46 def command @command end |
#log ⇒ Object (readonly)
Returns the value of attribute log.
46 47 48 |
# File 'lib/rundoc/code_command/background/process_spawn.rb', line 46 def log @log end |
#pid ⇒ Object (readonly)
Returns the value of attribute pid.
46 47 48 |
# File 'lib/rundoc/code_command/background/process_spawn.rb', line 46 def pid @pid end |
Class Method Details
.add(name, value) ⇒ Object
36 37 38 39 |
# 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) ⇒ Object
41 42 43 44 |
# 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 |
Instance Method Details
#alive? ⇒ Boolean
74 75 76 77 78 79 |
# File 'lib/rundoc/code_command/background/process_spawn.rb', line 74 def alive? return false unless @pid Process.kill(0, @pid) rescue Errno::ESRCH, Errno::EPERM false end |
#check_alive! ⇒ Object
87 88 89 |
# File 'lib/rundoc/code_command/background/process_spawn.rb', line 87 def check_alive! raise "#{@original_command} has exited unexpectedly: #{@log.read}" unless alive? end |
#stop ⇒ Object
81 82 83 84 85 |
# File 'lib/rundoc/code_command/background/process_spawn.rb', line 81 def stop return unless alive? Process.kill("TERM", -Process.getpgid(@pid)) Process.wait(@pid) end |
#wait(wait_value = nil, timeout_value = @timeout_value) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 |
# 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 (#{timeout_value}s) waiting for #{@command.inspect} to find a match using #{wait_value.inspect} in \n'#{log.read}'" end |