FalconSourceFalconServiceServer

class Server

A managed service for running Falcon servers.

Definitions

def initialize(...)

Initialize the server service.

Implementation

def initialize(...)
	super
	
	@listener = nil
end

def make_listener(evaluator, endpoint, bound_endpoint)

Build a listener from a configured and bound endpoint.

Signature

parameter evaluator Environment::Evaluator

The environment evaluator.

parameter endpoint Async::HTTP::Endpoint

The configured endpoint.

parameter bound_endpoint IO::Endpoint::BoundEndpoint

The bound endpoint.

returns Falcon::Listener

The bound listener.

Implementation

def make_listener(evaluator, endpoint, bound_endpoint)
	Listener.new(
		name: evaluator.name,
		scheme: endpoint.scheme,
		protocols: endpoint.protocol.names,
		endpoint: bound_endpoint,
	)
end

def bind_endpoint

Bind the endpoint used by each server worker.

Implementation

def bind_endpoint
	@endpoint = @evaluator.endpoint
	
	Sync do
		bound_endpoint = @endpoint.bound
		@listener = make_listener(@evaluator, @endpoint, bound_endpoint)
	end
	
	Console.info(self){"Starting #{self.name} on #{@endpoint}"}
end

def start

Prepare the bound endpoint for the server.

Implementation

def start
	bind_endpoint
	
	super
end

def with_listener(evaluator)

Yield the listener used by a server worker.

Signature

parameter evaluator Environment::Evaluator

The environment evaluator.

yields {|listener| ...}

The listener used by the worker.

parameter listener Falcon::Listener

The bound listener.

Implementation

def with_listener(evaluator)
	yield @listener
end

def setup(container)

Setup the service into the specified container.

Signature

parameter container Async::Container

The container to configure.

Implementation

def setup(container)
	container_options = @evaluator.container_options
	health_check_timeout = container_options[:health_check_timeout]
	
	container.run(**container_options) do |instance|
		clock = Async::Clock.start
		evaluator = self.environment.evaluator
		
		with_listener(evaluator) do |listener|
			Async do
				server = nil
				
				health_checker(instance, health_check_timeout) do
					if server
						instance.name = format_title(evaluator, server)
					end
				end
				
				instance.status!("Preparing...")
				evaluator.prepare_worker!(instance, listener)
				emit_prepared(instance, clock)
				
				instance.status!("Running...")
				server = run(instance, evaluator, listener)
				instance.name = format_title(evaluator, server)
				emit_running(instance, clock)
				
				instance.ready!
			end
		end
	end
end

def run(instance, evaluator, listener = @listener)

Run the service logic.

Signature

parameter instance Object

The container instance.

parameter evaluator Environment::Evaluator

The environment evaluator.

parameter listener Falcon::Listener

The listener used by this worker.

returns Falcon::Server

The server instance.

Implementation

def run(instance, evaluator, listener = @listener)
	if evaluator.respond_to?(:make_supervised_worker)
		Console.warn(self, "Async::Container::Supervisor is replaced by Async::Service::Supervisor, please update your service definition.")
		
		evaluator.make_supervised_worker(instance).run
	end
	
	server = evaluator.make_server(listener.endpoint)
	
	Async do |task|
		server.run
		
		task.children&.each(&:wait)
	end
	
	server
end

def stop(...)

Close the bound endpoint.

Implementation

def stop(...)
	if @listener
		@listener.close
		@listener = nil
	end
	
	@endpoint = nil
	
	super
end