Documentation
¶
Overview ¶
Package seamless implements a seamless restart strategy for daemons monitored by a service supervisor expecting non-forking daemons like daemontools, runit, systemd etc.
The seamless strategy is to fully rely on the service supervisor to restart the daemon, while providing to the daemon the full control of the restart process. To achieve this, seamless duplicates the daemon at startup in order to establish a supervisor -> launcher -> daemon relationship. The launcher is the first generation of the daemon hijacked by seamless to act as a circuit breaker between the supervisor and the supervised process.
This way, when the supervisor sends a TERM signal to stop the daemon, the launcher intercepts the signal and send an USR2 signal to its child (the actual daemon). In the daemon, seamless intercepts the USR2 signals to initiate the first stage of the seamless restart.
During the first stage, the daemon prepare itself to welcome a new version of itself by creating a PID file (see below) and by for instance closing file descriptors. At this point, the daemon is still supposed to accept requests. Once read, seamless sends a CHLD signal by default (or one defined by the user in SetParentTermSignal) back to the launcher (parent) on behalf of the child daemon. Upon reception, the launcher, immediately die, cutting to link between the supervisor and the daemon, making the supervisor attempting a restart of the daemon while current daemon is still running, detached and unsupervised.
Once the supervisor restarted the daemon, the daemon can start serving traffic in place of the old (still running) daemon by rebinding sockets using SO_REUSEPORT for instance (see different strategies in examples/). This is the second stage of the seamless restart. When ready, the new daemon calls seamless.Started which will look for a PID file, and if found, will send a TERM signal to the old daemon using the PID found in this file.
When the old daemon receives this TERM signal, the third and last stage of the seamless restart is engaged. The OnShutdown function is called so the daemon can gracefully shutdown using Go 1.8 http graceful Shutdown method for instance. This stage can last as long as you decide. When done, the old process can exit in order to conclude the seamless restart.
Seamless does not try to implement the actual graceful shutdown or to manage sockets migration. This task is left to the caller. See the examples directory for different implementations.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // LogMessage is used to log messages. The default implementation is to call // log.Print with the message. LogMessage = func(msg string) { log.Printf("seamless: %s", msg) } // LogError is used to log errors. The default implementation is to call // log.Printf with the message followed by the error. LogError = func(msg string, err error) { log.Printf("seamless: %s: %v", msg, err) } )
Functions ¶
func Init ¶
func Init(pidFile string)
Init initialize seamless. This method must be called as earliest as possible in the program flow, before any other goroutine are scheduled. This method must be called from the main goroutine, either from the main method or preferably from the init method in the main package.
The pidFile is used for signaling between the new and old generation of the daemon. If the pidFile is an empty string, seamless is disabled.
func OnChildDaemonLaunch ¶ added in v1.1.0
func OnChildDaemonLaunch(f func())
OnChildDaemonLaunch executes f() after successful launch of the child process by the launcher. f() should not be blocking. Typical use case include resource cleanups, logging etc.
func OnShutdown ¶
func OnShutdown(f func())
OnShutdown set f to be called when the graceful shutdown is engaged. When f returns, the graceful shutdown is considered done, and seamless.Wait will unblock.
func OnShutdownRequest ¶
func OnShutdownRequest(f func())
OnShutdownRequest set f to be called when a graceful shutdown is requested. This callback is optional and can be use to release some non-production resources that need to be release in order for the new daemon to start correctly.
The actual graceful shutdown should not be initiated at this stage. See OnShutdown for that.
func SetParentTermSignal ¶ added in v1.1.0
SetParentTermSignal allows user to define signal to send to the parent process to trigger shutdown of the parent (launcher) process. By default seamless sends SIGCHLD to the parent.
Types ¶
This section is empty.