Async::WebDriver SourceAsyncWebDriverBridgeProcessGroup

class ProcessGroup

A group of processes that are all killed when the group is closed.

Definitions

def self.spawn(*arguments)

Spawn a new process group with a given command.

Signature

parameter arguments Array

The command to execute.

Implementation

def self.spawn(*arguments)
	# This might be problematic...
	self.new(
		::Process.spawn(*arguments, pgroup: true, out: File::NULL, err: File::NULL)
	)
end

def initialize(pid)

Create a new process group from an existing process id.

Signature

parameter pid Integer

The process id.

Implementation

def initialize(pid)
	@pid = pid
	
	@status_task = Async(transient: true) do
		@status = ::Process.wait(@pid)
		
		unless @status.success?
			Console.error(self, "Process exited unexpectedly: #{@status}")
		end
	ensure
		self.close
	end
end

def close

Close the process group.

Implementation

def close
	if @status_task
		@status_task.stop
		@status_task = nil
	end
	
	if @pid
		::Process.kill("INT", -@pid)
		
		Async do |task|
			task.with_timeout(1) do
				::Process.wait(@pid)
			rescue Errno::ECHILD
				# Done.
			rescue Async::TimeoutError
				Console.info(self, "Killing pid #{@pid}...")
				::Process.kill("KILL", -@pid)
			end
		end.wait
		
		wait_all(-@pid)
		@pid = nil
	end
end

def wait_all(pgid)

Wait for all processes in the group to exit.

Implementation

def wait_all(pgid)
	while true
		pid, status = ::Process.wait2(pgid, ::Process::WNOHANG)
		
		break unless pid
	end
rescue Errno::ECHILD
	# Done.
end