huprt

package module
v0.0.0-...-c90031b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2015 License: BSD-2-Clause Imports: 5 Imported by: 0

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

View Source
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

type Error struct {
	Code  int
	Inner 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.

func (*Error) Error

func (e *Error) Error() string

type Hupd

type Hupd struct {
	Process

	RestartArg string
	Timeout    time.Duration
}

Hupd is responsible for restarting the host process and killing its parent process (if in the new process).

func (*Hupd) NotifyRestart

func (h *Hupd) NotifyRestart() error

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

func (h *Hupd) Restart() error

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.

func (*Hupd) Start

func (h *Hupd) Start(fromRestart bool) error

Start tells Hupd that the program is starting and whether it's starting up from a process that is restarting. If fromRestart is true, the parent process is sent a SIGTERM to tell it to exit.

If an error occurs when sending the SIGTERM, that error is returned.

type Process

type Process interface {
	BeginRestart(*exec.Cmd) error
	Kill()
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL