class MultiProcess::Process
Describes a single process that can be configured and run.
{Process} basically is just a thin wrapper around {ChildProcess}.
Attributes
ChildProcess object.
Command as full string.
Working directory for child process.
Current receiver. Defaults to `MultiProcess::Logger.global`.
Process
title used in e.g. logger
Public Class Methods
# File lib/multi_process/process.rb, line 21 def initialize(*args) args.flatten! opts = (Hash === args.last ? args.pop : {}) @title = opts[:title].to_s || args.first.to_s.strip.split(/\s+/, 2)[0] @command = args.map { |arg| (arg =~ /\A[\s"']+\z/ ? arg.inspect : arg).gsub '"', '\"' }.join(' ') @childprocess = create_childprocess *args @env = opts[:env] if Hash === opts[:env] @env_clean = opts[:clean_env].nil? ? true : !!opts[:clean_env] self.receiver = opts[:receiver] || MultiProcess::Logger.global self.dir = Dir.pwd self.dir = opts[:dir].to_s if opts[:dir] end
Public Instance Methods
Wait until process is available. See {#available?}.
@param opts [Hash] Options. @option opts [Integer] :timeout Timeout in seconds. Will raise
Timeout::Error if timeout is reached.
# File lib/multi_process/process.rb, line 94 def available!(opts = {}) timeout = opts[:timeout] ? opts[:timeout].to_i : MultiProcess::DEFAULT_TIMEOUT Timeout.timeout timeout do sleep 0.2 until available? end rescue Timeout::Error => ex raise Timeout::Error.new "Server #{id.inspect} on port #{port} didn't get up after #{timeout} seconds..." end
Check if server is available. What available means can be defined by subclasses e.g. a server process can check if server port is reachable.
By default is process if available if alive? returns true.
# File lib/multi_process/process.rb, line 84 def available? alive? end
Check if environment will be cleaned up for process.
Currently that includes wrapping the process start in `Bundler.with_clean_env` to remove bundler environment variables.
# File lib/multi_process/process.rb, line 140 def clean_env? !!@env_clean end
Set process working directory. Only affect process if set before starting.
# File lib/multi_process/process.rb, line 127 def dir=(dir) @dir = ::File.expand_path(dir.to_s) env['PWD'] = @dir end
Return current environment.
# File lib/multi_process/process.rb, line 146 def env @env ||= {} end
Set environment.
# File lib/multi_process/process.rb, line 152 def env=(env) fail ArgumentError.new 'Environment must be a Hash.' unless hash === env @env = env end
Set receiver that should receive process output.
# File lib/multi_process/process.rb, line 165 def receiver=(receiver) if @receiver childprocess.io.stdout.close childprocess.io.stderr.close end childprocess.io.stdout = receiver.pipe(self, :out) if receiver childprocess.io.stderr = receiver.pipe(self, :err) if receiver @receiver = receiver end
Start process and wait until it's finished.
Given arguments will be passed to {#wait}.
# File lib/multi_process/process.rb, line 114 def run(opts = {}) start wait opts end
Start process.
Started processes will be stopped when ruby VM exists by hooking into `at_exit`.
# File lib/multi_process/process.rb, line 62 def start return false if started? at_exit { stop } receiver.message(self, :sys, command) if receiver start_childprocess @started = true end
Check if process was started.
# File lib/multi_process/process.rb, line 106 def started? !!@started end
Stop process.
Will call `ChildProcess#stop`.
# File lib/multi_process/process.rb, line 75 def stop(*args) childprocess.stop *args if started? end
Wait until process finished.
If no timeout is given it will wait definitely.
@param opts [Hash] Options. @option opts [Integer] :timeout Timeout to wait in seconds.
# File lib/multi_process/process.rb, line 49 def wait(opts = {}) if opts[:timeout] childprocess.wait_for_exit opts[:timeout] else childprocess.wait end end
Private Instance Methods
Create child process.
# File lib/multi_process/process.rb, line 180 def create_childprocess(*args) ChildProcess.new *args.flatten end
Start child process.
Can be used to hook in subclasses and modules.
# File lib/multi_process/process.rb, line 188 def start_childprocess env.each { |k, v| childprocess.environment[k.to_s] = v.to_s } childprocess.cwd = dir if clean_env? Bundler.with_original_env { childprocess.start } else childprocess.start end end