Class: AssLauncher::Support::Shell::ProcessHolder Private

Inherits:
Object
  • Object
show all
Includes:
Platforms
Defined in:
lib/ass_launcher/support/shell/process_holder.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Note:

WARNIG!!! not forgot kill of threads created and handled of ProcessHolder

Note:

For run command used popen3 whith command_string and *args. It not shell running. If command.args.size == 0 in command.args array will be pushed one empty string. For more info see Process.spawn documentation

Class for running Command in subprocess and controlling him. Process run command in the thread. Thread waiting for process exit and call Command#exit_handling

Examples:

# Run command and witing for exit
ph = ProcessHolder.run(command, options)

result = ph.wait.result
raise 'bang!' unless result.sucsess?

# Run command and kill process when nidet

ph = ProcessHolder.run(command, options)

sleep 10 # for wakeup command

if ! ph.alive?
  raise 'command onexpected exit'
end

# doing something

ph.kill

# run and wait command

ph = ProcessHolder.run(command, options).wait

raise if ph.result.success?

Defined Under Namespace

Classes: KillProcessError, ProcessNotRunning, RunProcessError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Platforms

cygwin?, env, glob, linux?, path, path_class, windows?

Constructor Details

#initialize(command, options = {}) ⇒ ProcessHolder

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of ProcessHolder.

Parameters:

  • command (Command, Script)

    command runned in subprocess

  • options (Hash) (defaults to: {})

    options for Process.spawn

Raises:



126
127
128
129
130
131
132
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 126

def initialize(command, options = {})
  fail ArgumentError, 'Command was already running' if command.running?
  @command = command
  command.send(:process_holder=, self)
  @options = options
  options[:new_pgroup] = true if windows?
end

Instance Attribute Details

#commandCommand, Script (readonly)

Returns command runned in process.

Returns:



62
63
64
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 62

def command
  @command
end

#optionsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



69
70
71
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 69

def options
  @options
end

#pidFixnum (readonly)

Returns pid of runned process.

Returns:

  • (Fixnum)

    pid of runned process



54
55
56
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 54

def pid
  @pid
end

#popen3_threadObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



69
70
71
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 69

def popen3_thread
  @popen3_thread
end

#resultRunAssResult (readonly)

Returns result of execution command.

Returns:



58
59
60
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 58

def result
  @result
end

#threadThread (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns thread waiting for process.

Returns:

  • (Thread)

    thread waiting for process



66
67
68
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 66

def thread
  @thread
end

Class Method Details

.cmd_exe_with_c?(command) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

‘cmd /C command` not kill command when cmd killed

Returns:

  • (Boolean)


99
100
101
102
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 99

def self.cmd_exe_with_c?(command)
  shell_str = "#{command.cmd} #{command.args.join(' ')}"
  ! (shell_str =~ %r{(?<=\W|\A)cmd(.exe)?\s*(\/C)}i).nil?
end

.cmd_exe_with_k?(command) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

‘cmd /K command` not exit when exit command. Thread hangup

Returns:

  • (Boolean)


92
93
94
95
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 92

def self.cmd_exe_with_k?(command)
  shell_str = "#{command.cmd} #{command.args.join(' ')}"
  ! (shell_str =~ %r{(?<=\W|\A)cmd(.exe)?\s*(\/K)}i).nil?
end

.process_listArry<ProcessHolder>

Keep of created instaces

Returns:



76
77
78
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 76

def self.process_list
  @@process_slist ||= []
end

.run(command, options = {}) ⇒ ProcessHolder

Note:

WARNIG!!! not forgot kill of threads created and handled of ProcessHolder

Note:

For run command used popen3 whith command_string and *args. It not shell running. If command.args.size == 0 in command.args array will be pushed one empty string. For more info see Process.spawn documentation

Run command subprocess in new Thread and return instace for process controlling Thread wait process and handling process exit wihth Command#exit_handling

Parameters:

  • command (Command, Script)

    command runned in subprocess

  • options (Hash) (defaults to: {})

    options for Process.spawn

Returns:

Raises:



116
117
118
119
120
121
122
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 116

def self.run(command, options = {})
  fail RunProcessError, 'Forbidden run cmd.exe with /K key'\
    if cmd_exe_with_k? command
  h = new(command, options)
  reg_process h
  h.run
end

Instance Method Details

#alive?Boolean

True if thread alive

Returns:

  • (Boolean)

Raises:



205
206
207
208
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 205

def alive?
  fail ProcessNotRunning unless running?
  thread.alive?
end

#killself

Note:

WARNIG! for command runned as cmd /C commnd can’t get pid of command process. In this case error raised

Kill the process

Returns:

  • (self)

Raises:



184
185
186
187
188
189
190
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 184

def kill
  return self unless alive?
  fail KillProcessError, 'Can\'t kill subprocess runned in cmd.exe '\
    'on the windows machine' if self.class.cmd_exe_with_c? command
  Process.kill('KILL', pid)
  wait
end

#runself

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (self)

Raises:



136
137
138
139
140
141
142
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 136

def run
  fail RunProcessError, "Process was run. Pid: #{pid}" if running?
  @popen3_thread, stdout, stderr = run_process
  @pid = @popen3_thread.pid
  @thread = wait_process_in_thread(stdout, stderr)
  self
end

#running?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


144
145
146
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 144

def running?
  ! pid.nil?
end

#waitself

Wait for thread exit

Returns:

  • (self)

Raises:



196
197
198
199
200
# File 'lib/ass_launcher/support/shell/process_holder.rb', line 196

def wait
  return self unless alive?
  thread.join
  self
end