Skip to content
Elixir OTP application to gracefully stop the system after running shutdown hooks. Also catches SIGTERM.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
lib
test
.formatter.exs
.gitignore
.travis.yml
LICENSE
README.md
mix.exs

README.md

GracefulStop

Gracefully calls :init.stop() after running user-configured shutdown hooks.

Also catches SIGTERM signal to gracefully stop the system and run the shutdown hooks.

When running in a Kubernetes-managed cluster, nodes in the cluster come and go as kubernetes decides. It sends the SIGTERM signal, which by default triggers a :init.stop(). However, you might want to give the system some time to shut down, running cleanup processes, wait for running requests to finish, et cetera.

Usage

After adding :graceful_stop to your deps, you can configure it to call hooks when the application will stop:

config :graceful_stop, :hooks, [
  [IO, :puts, ["Stopping the system"]]
]

Then: kill $(pidof beam.smp) sends a SIGTERM signal to your running BEAM process, and you will notice that you see "Stopping the system" printed on the console, before it shuts down.

Note that these hooks run before any of your OTP applications are being stopped, so you can do all kinds of things there, without worrying that parts of your system are already shut down (which would be the case if you try to trap the {:EXIT, pid, :shutdown} message).

There is a :hook_timeout setting, defaulting to 15 seconds, which is the maximum time that a hook can run. Hooks run in parallel, using Task.async / Task.yield_many.

Inspiration

This project was inspired by the k8s_traffic_plug package and the corresponding blog post. However, it does not include a Plug. Creating a plug is simple, as you can call GracefulStop.get_status() which returns either :running or :stopping, and you can create a plug that serves a HTTP 503 request based on this code.

Installation

If available in Hex, the package can be installed by adding graceful_stop to your list of dependencies in mix.exs:

def deps do
  [
    {:graceful_stop, "~> 0.1.0"}
  ]
end
You can’t perform that action at this time.