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)


97
98
99
# File 'lib/hydra/derivatives/processors/shell_based_processor.rb', line 97

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
94
95
# 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]
  files = [stderr, stdout]
  stdin.close

  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
        Hydra::Derivatives::Logger.debug "Caught an eof error in ShellBasedProcessor"
        # No big deal.
      end
    end
  end

  stdout.close
  stderr.close
  exit_status = wait_thr.value

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