class Falcon::Controller::Serve

Uses {Server} for handling incoming requests.
A generic controller for serving an application.

def create_container

e.g. `Async::Container::Forked`.
Create the controller as specified by the command.
def create_container
	@command.container_class.new
end

def endpoint

The endpoint the server will bind to.
def endpoint
	@command.endpoint
end

def initialize(command, **options)

@parameter command [Command::Serve] The user-specified command-line options.
Initialize the server controller.
def initialize(command, **options)
	@command = command
	
	@endpoint = nil
	@bound_endpoint = nil
	@debug_trap = Async::IO::Trap.new(:USR1)
	
	super(**options)
end

def load_app

@returns [Protocol::HTTP::Middleware] an instance of the application to be served.
def load_app
	@command.load_app
end

def name

The name of the controller which is used for the process title.
def name
	"Falcon Server"
end

def setup(container)

@parameter container [Async::Container::Generic]
Setup the container with the application instance.
def setup(container)
	container.run(name: self.name, restart: true, **@command.container_options) do |instance|
		Async do |task|
			# Load one app instance per container:
			app = self.load_app
			
			task.async do
				if @debug_trap.install!
					Async.logger.info(instance) do
						"- Per-process status: kill -USR1 #{Process.pid}"
					end
				end
				
				@debug_trap.trap do
					Async.logger.info(self) do |buffer|
						task.reactor.print_hierarchy(buffer)
					end
				end
			end
			
			server = Falcon::Server.new(app, @bound_endpoint, @endpoint.protocol, @endpoint.scheme)
			
			server.run
			
			instance.ready!
			
			task.children.each(&:wait)
		end
	end
end

def start

Prepare the bound endpoint for the server.
def start
	@endpoint ||= self.endpoint
	
	@bound_endpoint = Async do
		Async::IO::SharedEndpoint.bound(@endpoint)
	end.wait
	
	Async.logger.info(self) { "Starting #{name} on #{@endpoint.to_url}" }
	
	@debug_trap.ignore!
	
	super
end

def stop(*)

Close the bound endpoint.
def stop(*)
	@bound_endpoint&.close
	
	@debug_trap.default!
	
	super
end