Module: Mbeditor::ProcessRunner

Defined in:
app/services/mbeditor/process_runner.rb

Defined Under Namespace

Classes: TimeoutError

Class Method Summary collapse

Class Method Details

.call(cmd, timeout: nil, env: {}, stdin_data: nil, chdir: nil) ⇒ Object

Raises:



11
12
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
40
41
42
43
44
45
46
# File 'app/services/mbeditor/process_runner.rb', line 11

def call(cmd, timeout: nil, env: {}, stdin_data: nil, chdir: nil)
  out = +""
  err = +""
  exit_status = nil
  timed_out = false

  opts = { pgroup: true }
  opts[:chdir] = chdir if chdir

  Open3.popen3(env, *cmd, **opts) do |stdin, stdout, stderr, wait_thr|
    stdin.write(stdin_data) if stdin_data
    stdin.close

    timer = if timeout
      Thread.new do
        sleep timeout
        timed_out = true
        Process.kill("-KILL", wait_thr.pid)
      rescue Errno::ESRCH
        nil
      end
    end

    out_thread = Thread.new { out = stdout.read }
    err_thread = Thread.new { err = stderr.read }
    out_thread.join
    err_thread.join

    exit_status = wait_thr.value
    timer&.kill
  end

  raise TimeoutError, "process timed out after #{timeout}s" if timed_out

  { stdout: out, stderr: err, exit_status: exit_status }
end