class Falcon::Service::Supervisor
Implements a host supervisor which can restart the host services and provide various metrics about the running processes.
Public Class Methods
Initialize the supervisor using the given environment. @parameter environment [Build::Environment]
Falcon::Service::Generic::new
# File lib/falcon/service/supervisor.rb, line 35 def initialize(environment) super @bound_endpoint = nil end
Public Instance Methods
Capture process metrics relating to the process group that the supervisor belongs to.
# File lib/falcon/service/supervisor.rb, line 60 def do_metrics(message) Process::Metrics::General.capture(pid: Process.ppid, ppid: Process.ppid) end
Restart the process group that the supervisor belongs to.
# File lib/falcon/service/supervisor.rb, line 48 def do_restart(message) # Tell the parent of this process group to spin up a new process group/container. # Wait for that to start accepting new connections. # Stop accepting connections. # Wait for existing connnections to drain. # Terminate this process group. signal = message[:signal] || :INT Process.kill(signal, Process.ppid) end
The endpoint which the supervisor will bind to. Typically a unix pipe in the same directory as the host.
# File lib/falcon/service/supervisor.rb, line 43 def endpoint @evaluator.endpoint end
Handle an incoming request. @parameter message [Hash] The decoded message.
# File lib/falcon/service/supervisor.rb, line 66 def handle(message) case message[:please] when 'restart' self.do_restart(message) when 'metrics' self.do_metrics(message) end end
Start the supervisor process which accepts connections from the bound endpoint and processes JSON formatted messages. @parameter container [Async::Container::Generic]
Falcon::Service::Generic#setup
# File lib/falcon/service/supervisor.rb, line 88 def setup(container) container.run(name: self.name, restart: true, count: 1) do |instance| Async do @bound_endpoint.accept do |peer| stream = Async::IO::Stream.new(peer) while message = stream.gets("\0") response = handle(JSON.parse(message, symbolize_names: true)) stream.puts(response.to_json, separator: "\0") end end instance.ready! end end super end
Bind the supervisor to the specified endpoint.
Falcon::Service::Generic#start
# File lib/falcon/service/supervisor.rb, line 76 def start Console.logger.info(self) {"Binding to #{self.endpoint}..."} @bound_endpoint = Async::Reactor.run do Async::IO::SharedEndpoint.bound(self.endpoint) end.wait super end
Release the bound endpoint.
Falcon::Service::Generic#stop
# File lib/falcon/service/supervisor.rb, line 108 def stop @bound_endpoint&.close @bound_endpoint = nil super end