Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion falcon.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = ">= 3.1"

spec.add_dependency "async"
spec.add_dependency "async-container", "~> 0.18"
spec.add_dependency "async-container", "~> 0.20"
spec.add_dependency "async-http", "~> 0.75"
spec.add_dependency "async-http-cache", "~> 0.4"
spec.add_dependency "async-service", "~> 0.10"
Expand Down
10 changes: 8 additions & 2 deletions lib/falcon/command/serve.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,22 @@ class Serve < Samovar::Command

option "--[no]-restart", "Enable/disable automatic restart.", default: true
option "--graceful-stop <timeout>", "Duration to wait for graceful stop.", type: Float, default: 1.0

option "--health-check-timeout <duration>", "Duration to wait for health check.", type: Float, default: 30.0
end

def container_options
@options.slice(:count, :forks, :threads, :restart)
@options.slice(:count, :forks, :threads, :restart, :health_check_timeout)
end

def endpoint_options
@options.slice(:hostname, :port, :timeout)
end

def name
@options[:hostname] || @options[:bind]
end

def environment
Async::Service::Environment.new(Falcon::Environment::Server).with(
Falcon::Environment::Rackup,
Expand All @@ -71,7 +77,7 @@ def environment
preload: [@options[:preload]].compact,
url: @options[:bind],

name: "server",
name: self.name,

endpoint: ->{Endpoint.parse(url, **endpoint_options)}
)
Expand Down
2 changes: 1 addition & 1 deletion lib/falcon/environment/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def count

# Options to use when creating the container.
def container_options
{restart: true, count: self.count}.compact
{restart: true, count: self.count, health_check_timeout: 30}.compact
end

# The host that this server will receive connections for.
Expand Down
48 changes: 48 additions & 0 deletions lib/falcon/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,53 @@ def self.middleware(rack_app, verbose: false, cache: true)
run rack_app
end
end

def initialize(...)
super

@accept_count = 0
@connection_count = 0

@request_count = 0
@active_count = 0
end

attr :request_count
attr :accept_count
attr :connect_count

def accept(...)
@accept_count += 1
@connection_count += 1

super
ensure
@connection_count -= 1
end

def call(...)
@request_count += 1
@active_count += 1

super
ensure
@active_count -= 1
end

def statistics_string
"C=#{format_count @connection_count}/#{format_count @accept_count} R=#{format_count @active_count}/#{format_count @request_count}"
end

private

def format_count(value)
if value > 1_000_000
"#{(value/1_000_000.0).round(2)}M"
elsif value > 1_000
"#{(value/1_000.0).round(2)}K"
else
value
end
end
end
end
12 changes: 12 additions & 0 deletions lib/falcon/service/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def start
# @parameter container [Async::Container::Generic]
def setup(container)
container_options = @evaluator.container_options
health_check_timeout = container_options[:health_check_timeout]

container.run(name: self.name, **container_options) do |instance|
evaluator = @environment.evaluator
Expand All @@ -63,6 +64,17 @@ def setup(container)

instance.ready!

if health_check_timeout
Async(transient: true) do
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while true
# We only update this if the health check is enabled. Maybe we should always update it?
instance.name = "#{self.name} (#{server.statistics_string} L=#{Fiber.scheduler.load.round(3)})"
sleep(health_check_timeout / 2)
instance.ready!
end
end
end

task.children.each(&:wait)
end
end
Expand Down
Loading