Class: Servolux::Prefork::Worker

Inherits:
Object
  • Object
show all
Defined in:
lib/servolux/prefork.rb

Overview

The worker encapsulates the forking of the child process and communication between the parent and the child. Each worker instance is extended with the block or module supplied to the pre-forking pool that created the worker.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(prefork, config) ⇒ Worker

Create a new worker that belongs to the prefork pool.

Parameters:

  • prefork (Prefork)

    The prefork pool that created this worker.

  • config (Hash)

    The worker configuration options.



372
373
374
375
376
377
378
379
# File 'lib/servolux/prefork.rb', line 372

def initialize( prefork, config )
  @timeout = prefork.timeout
  @config = config
  @thread = nil
  @piper = nil
  @error = nil
  @pid_list = []
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



365
366
367
# File 'lib/servolux/prefork.rb', line 365

def config
  @config
end

#errorObject (readonly)

Returns the value of attribute error.



363
364
365
# File 'lib/servolux/prefork.rb', line 363

def error
  @error
end

Instance Method Details

#alive?Boolean?

Returns true if the child process is alive. Returns nil if the child process has not been started.

Always returns nil when called from the child process.

Returns:

  • (Boolean, nil)


444
445
446
447
# File 'lib/servolux/prefork.rb', line 444

def alive?
  return if @piper.nil?
  @piper.alive?
end

#reapWorker

Internal: Attempt to reap any child processes spawned by this worker. If a child has exited, then we remove it from our PID list.

Returns:

  • (Worker)

    this worker instance.



453
454
455
456
457
458
459
# File 'lib/servolux/prefork.rb', line 453

def reap
  @piper.alive? unless @piper.nil?
  @pid_list.dup.each do |pid|
    @pid_list.delete(pid) if reap?(pid)
  end
  self
end

#reap?(pid) ⇒ Boolean

Internal: Check the return status of the given child PID. This will reap the process from the kernel process table if the child has exited.

Returns:

  • (Boolean)

    true if the PID has exited; false otherwise.



465
466
467
468
469
470
471
472
# File 'lib/servolux/prefork.rb', line 465

def reap?(pid)
  _, cstatus = Process.wait2(pid, Process::WNOHANG|Process::WUNTRACED)
  return true if cstatus
  Process.kill(0, pid)
  false
rescue Errno::ESRCH, Errno::ENOENT, Errno::ECHILD
  true
end

#signal(signal = 'TERM') ⇒ Integer? Also known as: kill

Send this given signal to the child process. The default signal is 'TERM'. This method will return immediately.

Parameters:

  • signal (String, Integer) (defaults to: 'TERM')

    The signal to send to the child process.

Returns:

  • (Integer, nil)

    The result of Process#kill or nil if called from the child process.



429
430
431
432
433
434
# File 'lib/servolux/prefork.rb', line 429

def signal( signal = 'TERM' )
  return if @piper.nil?
  @piper.signal signal
rescue Errno::ESRCH, Errno::ENOENT
  return nil
end

#startWorker

Start this worker. A new process will be forked, and the code supplied by the user to the prefork pool will be executed in the child process.

Returns:



386
387
388
389
390
391
392
# File 'lib/servolux/prefork.rb', line 386

def start
  @pid_list << @piper.pid if @piper
  @error = nil
  @piper = ::Servolux::Piper.new('rw', :timeout => @timeout)
  @piper.parent? ? parent : child
  self
end

#stopWorker?

Stop this worker. The internal worker thread is stopped and a 'HUP' signal is sent to the child process. This method will return immediately without waiting for the child process to exit. Use the wait method after calling stop if your code needs to know when the child exits.

Returns:



401
402
403
404
405
406
407
408
409
410
411
# File 'lib/servolux/prefork.rb', line 401

def stop
  return if @thread.nil? or @piper.nil? or @piper.child?

  @thread[:stop] = true
  @thread.wakeup if @thread.status
  close_parent
  signal 'TERM'
  @thread.join(0.5)
  @thread = nil
  self
end

#timed_out?Boolean?

Returns true if communication with the child process timed out. Returns nil if the child process has not been started.

Always returns nil when called from the child process.

Returns:

  • (Boolean, nil)


481
482
483
484
# File 'lib/servolux/prefork.rb', line 481

def timed_out?
  return if @piper.nil? or @piper.child?
  CommunicationError === @error
end

#waitObject

Wait for the child process to exit. This method returns immediately when called from the child process or if the child process has not yet been forked.



417
418
419
420
# File 'lib/servolux/prefork.rb', line 417

def wait
  return if @piper.nil? or @piper.child?
  @piper.wait(Process::WUNTRACED)
end