Class: Async::Container::Group

Inherits:
Object
  • Object
show all
Defined in:
lib/async/container/group.rb

Instance Method Summary collapse

Constructor Details

#initializeGroup

Returns a new instance of Group.



30
31
32
33
# File 'lib/async/container/group.rb', line 30

def initialize
	@pgid = nil
	@running = {}
end

Instance Method Details

#any?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/async/container/group.rb', line 47

def any?
	@running.any?
end

#closeObject



80
81
82
83
84
85
86
87
88
89
# File 'lib/async/container/group.rb', line 80

def close
	begin
		self.kill(:TERM)
	rescue Errno::EPERM
		# Sometimes, `kill` code can give EPERM, if any signal couldn't be delivered to a child. This might occur if an exception is thrown in the user code (e.g. within the fiber), and there are other zombie processes which haven't been reaped yet. These should be dealt with below, so it shouldn't be an issue to ignore this condition.
	end
	
	# Clean up zombie processes - if user presses Ctrl-C or for some reason something else blows up, exception would propagate back to caller:
	wait_all
end

#fork(&block) ⇒ Object



41
42
43
44
45
# File 'lib/async/container/group.rb', line 41

def fork(&block)
	if pid = ::Process.fork(&block)
		wait_for(pid)
	end
end

#kill(signal = :INT) ⇒ Object



67
68
69
# File 'lib/async/container/group.rb', line 67

def kill(signal = :INT)
	::Process.kill(signal, -@pgid) if @pgid
end

#spawn(*arguments) ⇒ Object



35
36
37
38
39
# File 'lib/async/container/group.rb', line 35

def spawn(*arguments)
	if pid = ::Process.spawn(*arguments)
		wait_for(pid)
	end
end

#stop(graceful = false) ⇒ Object



71
72
73
74
75
76
77
78
# File 'lib/async/container/group.rb', line 71

def stop(graceful = false)
	if graceful
		self.kill(:INT)
		wait_all
	end
ensure
	self.close
end

#waitObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/async/container/group.rb', line 51

def wait
	while self.any?
		self.wait_one
	end
rescue Interrupt
	# If the user interrupts the wait, interrupt the process group and wait for them to finish:
	self.kill(:INT)
	
	# If user presses Ctrl-C again (or something else goes wrong), we will come out and kill(:TERM) in the ensure below:
	wait_all

	raise
ensure
	self.close
end