Class: LitmusPaper::Dependency::Script

Inherits:
Object
  • Object
show all
Defined in:
lib/litmus_paper/dependency/script.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command, options = {}) ⇒ Script

Returns a new instance of Script.



8
9
10
11
# File 'lib/litmus_paper/dependency/script.rb', line 8

def initialize(command, options = {})
  @command = command
  @timeout = options.fetch(:timeout, 5)
end

Instance Attribute Details

#script_pidObject (readonly)

Returns the value of attribute script_pid.



6
7
8
# File 'lib/litmus_paper/dependency/script.rb', line 6

def script_pid
  @script_pid
end

Instance Method Details

#available?Boolean

Returns:

  • (Boolean)


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/litmus_paper/dependency/script.rb', line 13

def available?
  script_status = script_stdout = script_stderr = nil
  Open3.popen3(@command, :pgroup=>true) do |stdin, stdout, stderr, wait_thr|
    @script_pid = wait_thr.pid
    thstderr = Thread.new { stderr.read }
    thstdout = Thread.new { stdout.read }
    if !wait_thr.join(@timeout) # wait thread does not end within timeout
      kill_and_reap_script(-@script_pid) # kill the process group
      raise Timeout::Error
    end
    script_stderr = thstderr.value
    script_stdout = thstdout.value
    script_status = wait_thr.value
  end
  unless script_status.success?
    LitmusPaper.logger.info("Available check to #{@command} failed with status #{script_status.exitstatus}")
    LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
    LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
  end
  script_status.success?
rescue Timeout::Error
  LitmusPaper.logger.info("Timeout running command: '#{@command}'")
  false
rescue => e
  LitmusPaper.logger.info("Available check to #{@uri} failed with #{e.message}")
  false
end

#kill_and_reap_script(pid) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/litmus_paper/dependency/script.rb', line 41

def kill_and_reap_script(pid)
  Process.kill(9, pid)
  stop_time = Time.now + 2
  while Time.now < stop_time
    if Process.waitpid(pid, Process::WNOHANG)
      LitmusPaper.logger.info("Reaped PID #{pid}")
      return
    else
      sleep 0.1
    end
  end
  LitmusPaper.logger.error("Unable to reap PID #{pid}")
rescue Errno::ESRCH
  LitmusPaper.logger.info("Attempted to kill non-existent PID #{pid} (ESRCH)")
rescue Errno::ECHILD
  LitmusPaper.logger.info("Attempted to reap PID #{pid} but it has already been reaped (ECHILD)")
end

#to_sObject



59
60
61
# File 'lib/litmus_paper/dependency/script.rb', line 59

def to_s
  "Dependency::Script(#{@command})"
end