You can now give your VMs up to 24 hours to cleanly shutdown after receiving a kill signal. You can also specify the kill signal to send. Add these to your fly.toml to check it out:
kill_timeout: Number of seconds to wait before we force kill a VM. Minimum is 1 second, shared CPU VMs allow up to 5 minutes, dedicated CPU VMs allow up to 24 hours. Default is 5s.
kill_signal: Default is SIGINT, also allows SIGTERM , SIGQUIT , SIGUSR1 , SIGUSR2 , SIGKILL , or SIGSTOP.
If you’re curious how we terminate VMs, head to our blog to read more.
Would you consider shutdown scripts in addition to this?
Execute the script
Send signal
It’d be helpful for applications that have a http shutdown hook but shutdown too quickly on SIGINT/SIGTERM (eg Envoy and some other proxies)
The shutdown script would curl out to the shutdown http endpoint, sleep for 30/60s, then exit.
This is somewhat easily achieved with a sidecar container that can listen to the signal and start the slow and orderly shutdown of the main application.
Or send post to a global webhook receiver which could then trigger the shutdown logic based on instance id/ipv6, etc…
I’ve been doing a lot of work with this for DBs to make sure a leader steps down properly before it goes away. I think the right way to handle this is a supervisor process. I found a nice bash script to handle this:
prep_term()
{
unset term_child_pid
unset term_kill_needed
trap 'handle_term' TERM INT
}
handle_term()
{
if [ "${term_child_pid}" ]; then
kill -TERM "${term_child_pid}" 2>/dev/null
else
term_kill_needed="yes"
fi
}
wait_term()
{
term_child_pid=$!
if [ "${term_kill_needed}" ]; then
kill -TERM "${term_child_pid}" 2>/dev/null
fi
wait ${term_child_pid} 2>/dev/null
trap - TERM INT
wait ${term_child_pid} 2>/dev/null
}
# EXAMPLE USAGE
prep_term
/bin/something & # run your server
wait_term
You should be able to adjust wait_term to do what Envoy needs.
I did not expect to get good at bash while working on Fly but here we are.
Incidentally, if you feel like sharing your Envoy setup I think it would make a fabulous example app.
It is strangely satisfying. So far it’s good enough that we haven’t built a simple process supervisor to do these things, but sometimes I really wish I had a simple Go binary to interpolate environment variables into a config file.