Module: Hydra::Derivatives::Processors::ShellBasedProcessor::ClassMethods

Defined in:
lib/hydra/derivatives/processors/shell_based_processor.rb

Instance Method Summary collapse

Instance Method Details

#all_eof?(files) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/hydra/derivatives/processors/shell_based_processor.rb', line 95

def all_eof?(files)
  files.find { |f| !f.eof }.nil?
end

#execute(command) ⇒ Object



42
43
44
45
46
47
48
49
# File 'lib/hydra/derivatives/processors/shell_based_processor.rb', line 42

def execute(command)
  context = {}
  if timeout
    execute_with_timeout(timeout, command, context)
  else
    execute_without_timeout(command, context)
  end
end

#execute_with_timeout(timeout, command, context) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'lib/hydra/derivatives/processors/shell_based_processor.rb', line 51

def execute_with_timeout(timeout, command, context)
  Timeout.timeout(timeout) do
    execute_without_timeout(command, context)
  end
rescue Timeout::Error
  pid = context[:pid]
  Process.kill("KILL", pid)
  raise Hydra::Derivatives::TimeoutError, "Unable to execute command \"#{command}\"\nThe command took longer than #{timeout} seconds to execute"
end

#execute_without_timeout(command, context) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/hydra/derivatives/processors/shell_based_processor.rb', line 61

def execute_without_timeout(command, context)
  err_str = ''
  stdin, stdout, stderr, wait_thr = popen3(command)
  context[:pid] = wait_thr[:pid]
  stdin.close
  stdout.close
  files = [stderr]

  until all_eof?(files)
    ready = IO.select(files, nil, nil, 60)

    next unless ready
    readable = ready[0]
    readable.each do |f|
      fileno = f.fileno

      begin
        data = f.read_nonblock(BLOCK_SIZE)

        case fileno
        when stderr.fileno
          err_str << data
        end
      rescue EOFError
        Rails.logger "Caught an eof error in ShellBasedProcessor"
        # No big deal.
      end
    end
  end
  exit_status = wait_thr.value

  raise "Unable to execute command \"#{command}\". Exit code: #{exit_status}\nError message: #{err_str}" unless exit_status.success?
end