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

new(environment) click to toggle source

Initialize the supervisor using the given environment. @parameter environment [Build::Environment]

Calls superclass method Falcon::Service::Generic::new
# File lib/falcon/service/supervisor.rb, line 35
def initialize(environment)
        super
        
        @bound_endpoint = nil
end

Public Instance Methods

do_metrics(message) click to toggle source

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
do_restart(message) click to toggle source

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
endpoint() click to toggle source

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(message) click to toggle source

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
setup(container) click to toggle source

Start the supervisor process which accepts connections from the bound endpoint and processes JSON formatted messages. @parameter container [Async::Container::Generic]

Calls superclass method 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
start() click to toggle source

Bind the supervisor to the specified endpoint.

Calls superclass method 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
stop() click to toggle source

Release the bound endpoint.

Calls superclass method Falcon::Service::Generic#stop
# File lib/falcon/service/supervisor.rb, line 108
def stop
        @bound_endpoint&.close
        @bound_endpoint = nil
        
        super
end