application: add graceful shutdown config for Bandit
Configures Bandit with 615s drain timeout and 620s OTP shutdown window so in-flight Claude CLI calls (up to 600s) complete before systemd kills the process on restart. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
11a9026597
commit
244feb4d7e
@ -12,9 +12,26 @@ defmodule Symbiont.Application do
|
|||||||
└── Bandit (Symbiont.API) — HTTP API
|
└── Bandit (Symbiont.API) — HTTP API
|
||||||
|
|
||||||
In test mode, the supervisor starts empty — tests manage their own processes.
|
In test mode, the supervisor starts empty — tests manage their own processes.
|
||||||
|
|
||||||
|
## Graceful shutdown
|
||||||
|
|
||||||
|
Bandit is configured with a long ThousandIsland `shutdown_timeout` so that
|
||||||
|
in-flight `/task` requests (which can take up to 600s while Claude runs)
|
||||||
|
are not killed when systemd restarts the service. The Bandit child spec
|
||||||
|
also carries a matching `:shutdown` value so the OTP supervisor itself
|
||||||
|
waits long enough before forcing a kill.
|
||||||
|
|
||||||
|
The matching systemd unit must set `TimeoutStopSec=620` for this to take
|
||||||
|
effect end to end.
|
||||||
"""
|
"""
|
||||||
use Application
|
use Application
|
||||||
|
|
||||||
|
# 615s for Bandit to drain its sockets, 620s for the OTP child shutdown
|
||||||
|
# window. Keep these slightly larger than the Claude CLI timeout (600s)
|
||||||
|
# used by Muse's SMTP dispatcher.
|
||||||
|
@bandit_drain_ms 615_000
|
||||||
|
@bandit_child_shutdown_ms 620_000
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def start(_type, _args) do
|
def start(_type, _args) do
|
||||||
if Application.get_env(:symbiont, :port) == 0 do
|
if Application.get_env(:symbiont, :port) == 0 do
|
||||||
@ -32,13 +49,23 @@ defmodule Symbiont.Application do
|
|||||||
port = Application.get_env(:symbiont, :port, 8111)
|
port = Application.get_env(:symbiont, :port, 8111)
|
||||||
engram_db = Application.get_env(:symbiont, :engram_db, "/data/symbiont/engram.db")
|
engram_db = Application.get_env(:symbiont, :engram_db, "/data/symbiont/engram.db")
|
||||||
|
|
||||||
|
bandit_spec =
|
||||||
|
Supervisor.child_spec(
|
||||||
|
{Bandit,
|
||||||
|
plug: Symbiont.API,
|
||||||
|
port: port,
|
||||||
|
scheme: :http,
|
||||||
|
thousand_island_options: [shutdown_timeout: @bandit_drain_ms]},
|
||||||
|
shutdown: @bandit_child_shutdown_ms
|
||||||
|
)
|
||||||
|
|
||||||
children = [
|
children = [
|
||||||
{Task.Supervisor, name: Symbiont.TaskSupervisor},
|
{Task.Supervisor, name: Symbiont.TaskSupervisor},
|
||||||
{Symbiont.Ledger, data_dir: data_dir},
|
{Symbiont.Ledger, data_dir: data_dir},
|
||||||
{Symbiont.Queue, data_dir: data_dir},
|
{Symbiont.Queue, data_dir: data_dir},
|
||||||
{Symbiont.Engram, db_path: engram_db},
|
{Symbiont.Engram, db_path: engram_db},
|
||||||
{Symbiont.Heartbeat, []},
|
{Symbiont.Heartbeat, []},
|
||||||
{Bandit, plug: Symbiont.API, port: port, scheme: :http}
|
bandit_spec
|
||||||
]
|
]
|
||||||
|
|
||||||
opts = [strategy: :rest_for_one, name: Symbiont.Supervisor]
|
opts = [strategy: :rest_for_one, name: Symbiont.Supervisor]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user