Async::ContainerSourceAsyncContainerThreadedChild

class Child

Represents a running child thread from the point of view of the parent container.

Nested

Definitions

def self.fork(**options)

Start a new child thread and execute the provided block in it.

Signature

parameter options Hash

Additional options to to the new child instance.

Implementation

def self.fork(**options)
	self.new(**options) do |thread|
		::Thread.new do
			# This could be a configuration option (see forked implementation too):
			::Thread.handle_interrupt(SignalException => :immediate) do
				yield Instance.for(thread)
			end
		end
	end
end

def initialize(name: nil)

Initialize the thread.

Signature

parameter name String

The name to use for the child thread.

Implementation

def initialize(name: nil)
	super()
	
	@status = nil
	
	@thread = yield(self)
	@thread.report_on_exception = false
	@thread.name = name
	
	@waiter = ::Thread.new do
		begin
			@thread.join
		rescue Exit => exit
			finished(exit.error)
		rescue Interrupt
			# Graceful shutdown.
			finished
		rescue Exception => error
			finished(error)
		else
			finished
		end
	end
end

def as_json(...)

Convert the child process to a hash, suitable for serialization.

Signature

returns Hash

The request as a hash.

Implementation

def as_json(...)
	{
		name: @thread.name,
		status: @status&.as_json,
	}
end

def to_json(...)

Convert the request to JSON.

Signature

returns String

The request as JSON.

Implementation

def to_json(...)
	as_json.to_json(...)
end

def name= value

Set the name of the thread.

Signature

parameter value String

The name to set.

Implementation

def name= value
	@thread.name = value
end

def name

Get the name of the thread.

Signature

returns String

Implementation

def name
	@thread.name
end

def to_s

A human readable representation of the thread.

Signature

returns String

Implementation

def to_s
	"\#<#{self.class} #{@thread.name}>"
end

def close

Invoke #terminate! and then #wait for the child thread to exit.

Implementation

def close
	self.terminate!
	self.wait
ensure
	super
end

def interrupt!

Raise Interrupt = ::Interrupt in the child thread.

Implementation

def interrupt!
	@thread.raise(Interrupt)
end

def terminate!

Raise class Async::Container::Terminate in the child thread.

Implementation

def terminate!
	@thread.raise(Terminate)
end

def kill!

Invoke Thread#kill on the child thread.

Implementation

def kill!
	# Killing a thread does not raise an exception in the thread, so we need to handle the status here:
	@status = Status.new(:killed)
	
	@thread.kill
end

def restart!

Raise class Async::Container::Restart in the child thread.

Implementation

def restart!
	@thread.raise(Restart)
end

def wait

Wait for the thread to exit and return he exit status.

Signature

returns Status

Implementation

def wait
	if @waiter
		@waiter.join
		@waiter = nil
	end
	
	return @status
end

def finished(error = nil)

Invoked by the @waiter thread to indicate the outcome of the child thread.

Implementation

def finished(error = nil)
	if error
		Console.error(self) {error}
	end
	
	@status ||= Status.new(error)
	self.close_write
end