Class: ReplRunner::PtyParty

Inherits:
Object
  • Object
show all
Defined in:
lib/repl_runner/pty_party.rb

Constant Summary collapse

TIMEOUT =
1

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command) ⇒ PtyParty

Returns a new instance of PtyParty.



6
7
8
# File 'lib/repl_runner/pty_party.rb', line 6

def initialize(command)
  @output, @input, @pid = PTY.spawn(command)
end

Instance Attribute Details

#inputObject

Returns the value of attribute input.



3
4
5
# File 'lib/repl_runner/pty_party.rb', line 3

def input
  @input
end

#outputObject

Returns the value of attribute output.



3
4
5
# File 'lib/repl_runner/pty_party.rb', line 3

def output
  @output
end

#pidObject

Returns the value of attribute pid.



3
4
5
# File 'lib/repl_runner/pty_party.rb', line 3

def pid
  @pid
end

Instance Method Details

#close(timeout = TIMEOUT) ⇒ Object



21
22
23
24
25
26
27
28
29
30
# File 'lib/repl_runner/pty_party.rb', line 21

def close(timeout = TIMEOUT)
  Timeout::timeout(timeout) do
    input.close
    output.close
  end
rescue Timeout::Error
  # do nothing
ensure
  Process.kill('TERM', pid)   if pid.present?
end

#read(timeout = TIMEOUT, str = "") ⇒ Object

There be dragons - (You’re playing with process deadlock)

We want to read the whole output of the command First pull all contents from stdout (except we don’t know how many there are) So we have to go until our process deadlocks, then we timeout and return the string



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/repl_runner/pty_party.rb', line 38

def read(timeout = TIMEOUT, str = "")
  while true
    Timeout::timeout(timeout) do
      str << output.readline
      break if output.eof?
    end
  end

  return str
rescue Timeout::Error, EOFError, Errno::EIO
  return str
end

#run(cmd, timeout = TIMEOUT) ⇒ Object



16
17
18
19
# File 'lib/repl_runner/pty_party.rb', line 16

def run(cmd, timeout = TIMEOUT)
  write(cmd)
  return read(timeout)
end

#write(cmd) ⇒ Object



10
11
12
13
14
# File 'lib/repl_runner/pty_party.rb', line 10

def write(cmd)
  input.write(cmd)
rescue Errno::EIO => e
  raise e, "#{e.message} | trying to write '#{cmd}'"
end