graceful

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2020 License: MIT Imports: 14 Imported by: 3

README

graceful

Inspired by overseer and endless, with minimum codes and handy api to make http server graceful.

Prerequisite

  • golang 1.8+
  • linux/darwin(windows not supported)

Feature

  • Graceful reload http servers, zero downtime on upgrade.
  • Compatible with systemd, supervisor, etc.
  • Drop-in placement for http.ListenAndServe

Example

    type handler struct {
    }

    func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, port: %v, %q", r.Host, html.EscapeString(r.URL.Path))
    }

    func main(){
	    graceful.ListenAndServe(":9222", &handler{})
    }

multi servers:

    func main(){
        server := graceful.NewServer()
        server.Register("0.0.0.0:9223", &handler{})
        server.Register("0.0.0.0:9224", &handler{})
        server.Register("0.0.0.0:9225", &handler{})
        err := server.Run()
        fmt.Printf("error: %v\n", err)
    }

More example checkout example folder.

Reload

SIGHUP and SIGUSR1 on master proccess are used as default to reload server. server.Reload() func works as well from your code.

Drawbacks

graceful starts a master process to keep pid unchaged for process managers(systemd, supervisor, etc.), and a worker proccess listen to actual addrs. That means graceful starts one more process. Fortunately, master proccess waits for signals and reload worker when neccessary, which is costless since reload is usually low-frequency action.

Default values

  • StopTimeout. Unfinished old connections will be drop in {StopTimeout} seconds, default 20s, after new server is up.
	server := graceful.NewServer(graceful.WithStopTimeout(time.Duration(4 * time.Hour)))
	server.Register(addr, handler)
	if err := server.Run(); err != nil {
		log.Fatal(err)
	}
  • Signals. Default reload signals: syscall.SIGHUP, syscall.SIGUSR1 and stop signals: syscall.SIGKILL, syscall.SIGTERM, syscall.SIGINT could be overwrited with:
	server := graceful.NewServer(graceful.WithStopSignals([]syscall.Signal{syscall.SIGKILL}), graceful.WithReloadSignals([]syscall.Signal{syscall.SIGHUP}))
	server.Register(addr, handler)
	if err := server.Run(); err != nil {
		log.Fatal(err)
	}

TODO

  • ListenAndServeTLS
  • Add alternative api: Run in single process without master-worker

Documentation

Index

Constants

View Source
const (
	EnvWorker       = "GRACEFUL_WORKER"
	EnvNumFD        = "GRACEFUL_NUMFD"
	EnvOldWorkerPid = "GRACEFUL_OLD_WORKER_PID"
	EnvParentPid    = "GRACEFUL_PARENT_PID"
	ValWorker       = "1"
)

constants

Variables

View Source
var (
	ErrNoServers = errors.New("no servers")
)
View Source
var (
	StartedAt time.Time
)

Functions

func IsMaster

func IsMaster() bool

func IsWorker

func IsWorker() bool

func ListenAndServe

func ListenAndServe(addr string, handler http.Handler) error

ListenAndServe starts server with (addr, handler)

Types

type Option

type Option func(o *option)

func WithReloadSignals

func WithReloadSignals(sigs []syscall.Signal) Option

WithReloadSignals set reload signals, otherwise, default ones are used

func WithStopSignals

func WithStopSignals(sigs []syscall.Signal) Option

WithStopSignals set stop signals, otherwise, default ones are used

func WithStopTimeout

func WithStopTimeout(timeout time.Duration) Option

WithStopTimeout set stop timeout for graceful shutdown

if timeout occurs, running connections will be discard violently.

func WithWatchInterval

func WithWatchInterval(timeout time.Duration) Option

WithWatchInterval set watch interval for worker checking master process state

type Server

type Server struct {
	// contains filtered or unexported fields
}

func NewServer

func NewServer(opts ...Option) *Server

func (*Server) Register

func (s *Server) Register(addr string, handler http.Handler)

Register an addr and its corresponding handler all (addr, handler) pair will be started with server.Run

func (*Server) RegisterUnix

func (s *Server) RegisterUnix(addr string, handler http.Handler)

RegisterUnix register (addr, handler) on unix socket

func (*Server) Reload

func (s *Server) Reload() error

Reload reload server gracefully

func (*Server) Run

func (s *Server) Run() error

Run runs all register servers

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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