Class: Selenium::WebDriver::ChildProcess

Inherits:
Object
  • Object
show all
Defined in:
lib/selenium/webdriver/child_process.rb

Overview

Cross platform child process launcher

Defined Under Namespace

Modules: IronRubyProcess, JRubyProcess, WindowsProcess

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ ChildProcess

Returns a new instance of ChildProcess.


13
14
15
16
17
18
19
20
21
22
23
# File 'lib/selenium/webdriver/child_process.rb', line 13

def initialize(*args)
  @args = args

  if Platform.jruby?
    extend JRubyProcess
  elsif Platform.ironruby?
    extend IronRubyProcess
  elsif Platform.os == :windows
    extend WindowsProcess
  end
end

Instance Attribute Details

#pidObject (readonly)

Returns the value of attribute pid


11
12
13
# File 'lib/selenium/webdriver/child_process.rb', line 11

def pid
  @pid
end

Instance Method Details

#assert_startedObject


114
115
116
# File 'lib/selenium/webdriver/child_process.rb', line 114

def assert_started
  raise Error::WebDriverError, "process not started" unless @pid
end

#ensure_deathObject

Tries increasingly harsher methods to make the process die within a reasonable time


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/selenium/webdriver/child_process.rb', line 56

def ensure_death
  begin
    $stderr.puts "wait_nonblock(5) -> #{self}" if $DEBUG
    return wait_nonblock(5)
  rescue Error::TimeOutError
    # try next
  end

  $stderr.puts "TERM -> #{self}" if $DEBUG
  kill

  begin
    $stderr.puts "wait_nonblock(5) -> #{self}" if $DEBUG
    return wait_nonblock(5)
  rescue Error::TimeOutError
    # try next
  end

  $stderr.puts "KILL -> #{self}" if $DEBUG
  kill!

  $stderr.puts "wait_nonblock(5) -> #{self}" if $DEBUG
  wait_nonblock(5)
rescue Errno::ECHILD
  # great!
  true
end

#exit_valueObject

Returns the exit value of the process, or nil if it's still alive.


34
35
36
37
# File 'lib/selenium/webdriver/child_process.rb', line 34

def exit_value
  pid, status = Process.waitpid2(@pid, Process::WNOHANG)
  status.exitstatus if pid
end

#killObject


104
105
106
107
# File 'lib/selenium/webdriver/child_process.rb', line 104

def kill
  assert_started
  Process.kill('TERM', @pid)
end

#kill!Object


109
110
111
112
# File 'lib/selenium/webdriver/child_process.rb', line 109

def kill!
  assert_started
  Process.kill('KILL', @pid)
end

#startObject


39
40
41
42
43
44
45
46
47
48
49
# File 'lib/selenium/webdriver/child_process.rb', line 39

def start
  @pid = fork do
    unless $DEBUG
      [STDOUT, STDERR].each { |io| io.reopen("/dev/null") }
    end

    exec(*@args)
  end

  self
end

#ugly_death?Boolean

Returns:

  • (Boolean)

25
26
27
28
# File 'lib/selenium/webdriver/child_process.rb', line 25

def ugly_death?
  code = exit_value
  code && code != 0
end

#waitObject


97
98
99
100
101
102
# File 'lib/selenium/webdriver/child_process.rb', line 97

def wait
  assert_started
  Process.waitpid2 @pid
rescue Errno::ECHILD
  nil
end

#wait_nonblock(timeout) ⇒ Object


84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/selenium/webdriver/child_process.rb', line 84

def wait_nonblock(timeout)
  end_time = Time.now + timeout
  until Time.now > end_time || exited = exit_value
    sleep 0.1
  end

  unless exited
    raise Error::TimeOutError, "process still alive after #{timeout} seconds"
  end

  exited
end