Class: Aruba::Processes::SpawnProcess

Inherits:
BasicProcess show all
Defined in:
lib/aruba/processes/spawn_process.rb

Overview

Spawn a process for command

SpawnProcess is not meant for direct use - SpawnProcess.new - by users. Only it's public methods are part of the public API of aruba, e.g. #stdin, #stdout.

Instance Attribute Summary

Attributes inherited from BasicProcess

#environment, #exit_status, #exit_timeout, #io_wait_timeout, #main_class, #startup_wait_time, #stop_signal, #working_directory

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BasicProcess

#after_run, #arguments, #before_run, #command, #commandline, #empty?, #inspect, #output, #restart, #started?, #stopped?, #timed_out?

Constructor Details

#initialize(cmd, exit_timeout, io_wait_timeout, working_directory, environment = Aruba.platform.environment_variables.hash_from_env, main_class = nil, stop_signal = nil, startup_wait_time = 0) ⇒ SpawnProcess

Create process



131
132
133
134
135
136
137
138
139
# File 'lib/aruba/processes/spawn_process.rb', line 131

def initialize(cmd, exit_timeout, io_wait_timeout, working_directory, # rubocop:disable Metrics/ParameterLists
               environment = Aruba.platform.environment_variables.hash_from_env,
               main_class = nil, stop_signal = nil, startup_wait_time = 0)
  super

  @process      = nil
  @stdout_cache = nil
  @stderr_cache = nil
end

Class Method Details

.match?(_mode) ⇒ Boolean

Use as default launcher



102
103
104
# File 'lib/aruba/processes/spawn_process.rb', line 102

def self.match?(_mode)
  true
end

Instance Method Details

#close_io(name) ⇒ Object

Close io



245
246
247
248
249
# File 'lib/aruba/processes/spawn_process.rb', line 245

def close_io(name)
  return if stopped?

  @process.public_send(name.to_sym).close
end

#contentString

Content of command



327
328
329
# File 'lib/aruba/processes/spawn_process.rb', line 327

def content
  File.read command_path
end

#filesystem_statusAruba::Platforms::FilesystemStatus

Return file system stats for the given command



318
319
320
# File 'lib/aruba/processes/spawn_process.rb', line 318

def filesystem_status
  Aruba.platform.filesystem_status.new(command_path)
end

#interactive?Boolean



331
332
333
# File 'lib/aruba/processes/spawn_process.rb', line 331

def interactive?
  true
end

#pidObject

Output pid of process

This is the PID of the spawned process.



297
298
299
# File 'lib/aruba/processes/spawn_process.rb', line 297

def pid
  @process.pid
end

#send_signal(signal) ⇒ Object

Send command a signal



305
306
307
308
309
310
311
312
# File 'lib/aruba/processes/spawn_process.rb', line 305

def send_signal(signal)
  error_message = %(Command "#{commandline}" with PID "#{pid}" has already stopped.)
  raise CommandAlreadyStoppedError, error_message if @process.exited?

  Process.kill signal, pid
rescue Errno::ESRCH
  raise CommandAlreadyStoppedError, error_message
end

#start {|SpawnProcess| ... } ⇒ Object

Run the command

Yields:



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/aruba/processes/spawn_process.rb', line 146

def start
  if started?
    error_message =
      "Command \"#{commandline}\" has already been started. " \
      'Please `#stop` the command first and `#start` it again. ' \
      'Alternatively use `#restart`.'
    raise CommandAlreadyStartedError, error_message
  end

  @started = true

  @process = ProcessRunner.new(command_string.to_a)

  @stdout_file = Tempfile.new('aruba-stdout-')
  @stderr_file = Tempfile.new('aruba-stderr-')

  @stdout_file.sync = true
  @stderr_file.sync = true

  @stdout_file.set_encoding('ASCII-8BIT')
  @stderr_file.set_encoding('ASCII-8BIT')

  @exit_status = nil

  before_run

  @process.stdout = @stdout_file
  @process.stderr = @stderr_file
  @process.cwd    = @working_directory

  @process.environment = environment

  begin
    @process.start
    sleep startup_wait_time
  rescue SystemCallError => e
    raise LaunchError, "It tried to start #{commandline}. " + e.message
  end

  after_run

  yield self if block_given?
end

#stderr(opts = {}) ⇒ String

Access to stderr of process



226
227
228
229
230
231
232
233
# File 'lib/aruba/processes/spawn_process.rb', line 226

def stderr(opts = {})
  return @stderr_cache if stopped?

  wait_for_io opts.fetch(:wait_for_io, io_wait_timeout) do
    @process.stderr.flush
    open(@stderr_file.path).read
  end
end

#stdinObject

Access to stdin of process



191
192
193
194
195
# File 'lib/aruba/processes/spawn_process.rb', line 191

def stdin
  return if @process.exited?

  @process.io.stdin
end

#stdout(opts = {}) ⇒ String

Access to stdout of process



207
208
209
210
211
212
213
214
# File 'lib/aruba/processes/spawn_process.rb', line 207

def stdout(opts = {})
  return @stdout_cache if stopped?

  wait_for_io opts.fetch(:wait_for_io, io_wait_timeout) do
    @process.stdout.flush
    open(@stdout_file.path).read
  end
end

#stopObject

Stop command



252
253
254
255
256
257
258
# File 'lib/aruba/processes/spawn_process.rb', line 252

def stop(*)
  return @exit_status if stopped?

  @process.poll_for_exit(@exit_timeout) or @timed_out = true

  terminate
end

#terminateObject

Terminate command



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/aruba/processes/spawn_process.rb', line 266

def terminate
  return @exit_status if stopped?

  unless @process.exited?
    if @stop_signal
      # send stop signal ...
      send_signal @stop_signal
      # ... and set the exit status
      wait
    else
      begin
        @process.stop
      rescue Errno::EPERM # This can occur on MacOS
        nil
      end
    end
  end

  @exit_status = @process.exit_code

  @stdout_cache = read_temporary_output_file @stdout_file
  @stderr_cache = read_temporary_output_file @stderr_file

  @started = false

  @exit_status
end

#waitObject

Wait for command to finish



261
262
263
# File 'lib/aruba/processes/spawn_process.rb', line 261

def wait
  @process.wait
end

#write(input) ⇒ Object



235
236
237
238
239
240
241
242
# File 'lib/aruba/processes/spawn_process.rb', line 235

def write(input)
  return if stopped?

  @process.stdin.write(input)
  @process.stdin.flush

  self
end