Documentation ¶
Overview ¶
Package huprt embodies simple process-restarting logic via a SIGHUP signal. This is similar to other Go packages, but only intended to cover the handshake in restarting a process. It does not manage HTTP[S] server lifecycles, requests, or anything else.
BUG(ncower): Due to the dependency on Unix signals and the sys/unix package, the huprt package is not expected to work on Windows or non-Unix systems. Future work-arounds for this may reduce the dependence on signals but require other IPC methods. For now, not supporting Windows is acceptable.
Index ¶
Constants ¶
const ( ErrTimeout int = iota // huprt: process restart timed out ErrNewProcess // huprt: error starting new process ErrKillProcess // huprt: error killing parent process ErrRestart // huprt: restart error ErrNoProcess // huprt: Hupd.Process is nil )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Error ¶
Error represents a huprt error. All errors returned by huprt all contain an error code identifying where the error originated from as well as an additional inner error that triggered this error.
There are no un-wrapped errors returned by huprt.
type Hupd ¶
Hupd is responsible for restarting the host process and killing its parent process (if in the new process).
func (*Hupd) NotifyRestart ¶
NotifyRestart waits for a SIGHUP and, once-received, attempts to restart the process. Returns any error that occurs. This function is intended to be run in a separate goroutine, as it will block until a SIGHUP is received.
It is effectively a convenience function for calling signal.Notify, waiting for a signal, and calling the Hupd Restart method.
func (*Hupd) Restart ¶
Restart tells Hupd to restart this process. If the Hupd's RestartArg field is empty, the restart argument passed to the new process defaults to "-restart". It is assumed to always be the first argument. As such, only the first argument is checked for it. If it's not the first argument, it is prepended to the argument list passed to the new process.
type Process ¶
Process defines an interface for any process that can be killed so that it may be restarted. Only one Process is intended to exist per-program.
The BeginRestart method is called first to signal that any resources held by the process should be released. This method must block until all critical resources that a new process would consume are released (e.g., files, sockets, locks, and others). Non-critical resources can be released asynchronously.
Any resources, such as file descriptors, can be passed to the new process by configuring the Cmd passed to BeginRestart.
Once BeginRestart has completed, and provided that the Cmd has not been configured incorrectly, a new process is started using that Cmd. Once successfully started, the new process will notify the old one via SIGTERM that it should exit. At that point, the Kill method is called and the program must exit.
If at any point during this process an error occurs, such as if BeginRestart returns an error or the new process cannot be started, the Hupd will return an error and allow the program to decide how to proceed. The Kill method is never called if an error is returned.
It is particularly important, during BeginRestart, to stop handling SIGTERM, as Hupd uses this to know when to invoke its Kill method.
Essentially, the flow from Hupd.Restart to BeginRestart to Kill behaves roughly like the following diagram:
┌─In Old Process ───────────────────────────────────────────────┐ │ │ SIGHUP │ ┌─────────────┐ Prepare ┌───────────────────┐ Spawn │ ┌─────────────┐ ────────▶│ Old Process │──────────▶│ BeginRestart(cmd) │─ ─ ─ ─ ─ ─ ─ ─│─▶│ New Process │ │ └─────────────┘ └───────────────────┘ │ └─────────────┘ │ ▲ ┌───────────────────┐ │ │ │ └──────────────────│ Kill() │◀ ─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ │ Exit └───────────────────┘ Recv SIGTERM │ Send SIGTERM │ │ └───────────────────────────────────────────────────────────────┘
Notes ¶
Bugs ¶
Due to the dependency on Unix signals and the sys/unix package, the huprt package is not expected to work on Windows or non-Unix systems. Future work-arounds for this may reduce the dependence on signals but require other IPC methods. For now, not supporting Windows is acceptable.