Handle polling without the healthcheck config

This commit is contained in:
Donal McBreen
2024-09-12 19:27:59 +01:00
parent d2672c771e
commit 8b965b0a31
7 changed files with 77 additions and 14 deletions

View File

@@ -4,7 +4,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
with_lock do
say "Get most recent version available as an image...", :magenta unless options[:version]
using_version(version_or_latest) do |version|
say "Start container with version #{version} using a #{KAMAL.config.readiness_delay}s readiness delay (or reboot if already running)...", :magenta
say "Start container with version #{version} (or reboot if already running)...", :magenta
# Assets are prepared in a separate step to ensure they are on all hosts before booting
on(KAMAL.hosts) do

View File

@@ -58,6 +58,9 @@ class Kamal::Cli::App::Boot
else
Kamal::Cli::Healthcheck::Poller.wait_for_healthy(pause_after_ready: true) { capture_with_info(*app.status(version: version)) }
end
rescue => e
error "Failed to boot #{role} on #{host}"
raise e
end
def stop_new_version

View File

@@ -1,22 +1,30 @@
module Kamal::Cli::Healthcheck::Poller
extend self
def wait_for_healthy(pause_after_ready: false, &block)
def wait_for_healthy(role, &block)
attempt = 1
max_attempts = 7
timeout_at = Time.now + KAMAL.config.readiness_timeout
readiness_delay = KAMAL.config.readiness_delay
begin
case status = block.call
when "healthy"
when "running" # No health check configured
sleep KAMAL.config.readiness_delay if pause_after_ready
else
raise Kamal::Cli::Healthcheck::Error, "container not ready (#{status})"
status = block.call
if status == "running"
# Wait for the readiness delay and confirm it is still running
if readiness_delay > 0
info "Container is running, waiting for readiness delay of #{readiness_delay} seconds"
sleep readiness_delay
status = block.call
end
end
unless %w[ running healthy ].include?(status)
raise Kamal::Cli::Healthcheck::Error, "container not ready after #{KAMAL.config.readiness_timeout} seconds (#{status})"
end
rescue Kamal::Cli::Healthcheck::Error => e
if attempt <= max_attempts
info "#{e.message}, retrying in #{attempt}s (attempt #{attempt}/#{max_attempts})..."
sleep attempt
time_left = timeout_at - Time.now
if time_left > 0
sleep [ attempt, time_left ].min
attempt += 1
retry
else

View File

@@ -189,6 +189,10 @@ class Kamal::Configuration
raw_config.readiness_delay || 7
end
def readiness_timeout
raw_config.readiness_timeout || 30
end
def run_directory
".kamal"

View File

@@ -111,9 +111,15 @@ minimum_version: 1.3.0
# Readiness delay
#
# Seconds to wait for a container to boot after is running, default 7
# This only applies to containers that do not specify a healthcheck
# This only applies to containers that do not run a proxy or specify a healthcheck
readiness_delay: 4
# Readiness timeout
#
# How long to wait for a container to become ready, default 30
# This only applies to containers that do not run a proxy
readiness_timeout: 4
# Run directory
#
# Directory to store kamal runtime files in on the host, default `.kamal`