Class: WebConsole::Slave

Inherits:
Object
  • Object
show all
Defined in:
lib/web_console/slave.rb

Overview

Slave\ Process\ Wrapper

Creates and communicates with slave processses.

The communication happens through an input with attached psuedo-terminal. All of the communication is done in asynchrouns way, meaning that when you send input to the process, you have get the output by polling for it.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command = WebConsole.config.command, options = {}) ⇒ Slave

Returns a new instance of Slave.



16
17
18
19
20
21
# File 'lib/web_console/slave.rb', line 16

def initialize(command = WebConsole.config.command, options = {})
  using_term(options[:term] || WebConsole.config.term) do
    @output, @input, @pid = PTY.spawn(command.to_s)
  end
  configure(options)
end

Instance Attribute Details

#pidObject (readonly)

The slave process id.



14
15
16
# File 'lib/web_console/slave.rb', line 14

def pid
  @pid
end

Instance Method Details

#configure(options = {}) ⇒ Object

Configure the psuedo terminal properties.

Options:

:width  The width of the terminal in number of columns.
:height The height of the terminal in number of rows.

If any of the width or height is missing (or zero), the termininal size won’t be set.



31
32
33
34
# File 'lib/web_console/slave.rb', line 31

def configure(options = {})
  dimentions = options.values_at(:height, :width).collect(&:to_i)
  @input.winsize = dimentions unless dimentions.any?(&:zero?)
end

#dispose(options = {}) ⇒ Object

Dispose the underlying process, sending SIGTERM.

After the process is disposed, it is detached from the parent to prevent zombies.

If the process is already disposed an Errno::ESRCH will be raised and handled internally. If you want to handle Errno::ESRCH yourself, pass {raise: true} as options.

Returns a thread, which can be used to wait for the process termination.



87
88
89
# File 'lib/web_console/slave.rb', line 87

def dispose(options = {})
  dispose_with(:SIGTERM, options)
end

#dispose!(options = {}) ⇒ Object

Dispose the underlying process, sending SIGKILL.

After the process is disposed, it is detached from the parent to prevent zombies.

If the process is already disposed an Errno::ESRCH will be raised and handled internally. If you want to handle Errno::ESRCH yourself, pass {raise: true} as options.

Returns a thread, which can be used to wait for the process termination.



101
102
103
# File 'lib/web_console/slave.rb', line 101

def dispose!(options = {})
  dispose_with(:SIGKILL, options)
end

#pending_output(chunk_len = 4096) ⇒ Object

Gets the pending output of the process.

The pending output is read in an non blocking way by chunks, in the size of chunk_len. By default, chunk_len is 4096 bytes.

Returns nil, if there is no pending output at the moment. Otherwise, returns the output that hasn’t been read since the last invocation.

Raises Errno:EIO on closed output stream. This can happen if the underlying process exits.



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/web_console/slave.rb', line 64

def pending_output(chunk_len = 4096)
  # Returns nil if there is no pending output.
  return unless pending_output?

  pending = String.new
  while chunk = @output.read_nonblock(chunk_len)
    pending << chunk
  end
  pending.force_encoding('UTF-8')
rescue IO::WaitReadable
  pending.force_encoding('UTF-8')
end

#pending_output?(timeout = WebConsole.config.timeout) ⇒ Boolean

Returns whether the slave process has any pending output in wait seconds.

By default, the timeout follows config.web_console.timeout. Usually, it is zero, making the response immediate.

Returns:

  • (Boolean)


49
50
51
52
# File 'lib/web_console/slave.rb', line 49

def pending_output?(timeout = WebConsole.config.timeout)
  # JRuby's select won't automatically coerce ActiveSupport::Duration.
  !!IO.select([@output], [], [], timeout.to_i)
end

#send_input(input) ⇒ Object

Sends input to the slave process STDIN.

Returns immediately.

Raises:

  • (ArgumentError)


39
40
41
42
# File 'lib/web_console/slave.rb', line 39

def send_input(input)
  raise ArgumentError if input.nil? or input.try(:empty?)
  input.each_char { |char| @input.putc(char) }
end