zerodt

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2018 License: MIT Imports: 18 Imported by: 0

README

ZeroDT

GoDoc Build Status Go Report Status

Package ZeroDT offers a zero downtime restart and a graceful shutdown for HTTP servers. Key features:

  • supported both stateless and stateful servers
  • compatible with systemd's socket activation
  • based on out-of-the-box http.Server
  • work with any number of servers
  • not a framework

Example

The simplest way to use ZeroDT is to pass your http.Server to the zerodt.NewApp function and call zerodt.ListenAndServe for an object it returns:

package main

import (
    "io"
    "net/http"
    "time"

    "github.com/ssgreg/zerodt"
)

func hello(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Hello world!")
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", hello)

    a := zerodt.NewApp(&http.Server{Addr: ":8081", Handler: mux})
    a.ListenAndServe()
}

Adopting your HTTP server to use as systemd's service

Under construction

Documentation

Overview

Package zerodt offers a zero downtime restart and a graceful shutdown for HTTP servers.

The simplest way to use ZeroDT is to pass your http.Server to the NewApp() function and call ListenAndServe() for an object it returns:

package main

import (
	"io"
	"net/http"
	"time"

	"github.com/ssgreg/zerodt"
)

func hello(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Hello world!")
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", hello)

	a := zerodt.NewApp(&http.Server{Addr: ":8081", Handler: mux})
	a.ListenAndServe()
}

For more details visit https://github.com/ssgreg/zerodt

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetLogger

func SetLogger(l StdLogger)

SetLogger allows to set a different logger that is compatible with StdLogger interface. Tested with stdlib logger:

log.New(os.Stderr, "", log.LstdFlags)

And sirupsen/logrus:

logrus.StandardLogger()

Types

type App

type App struct {
	// PreServeFn is a common hook which notifies client that all servers are
	// about to start serving.
	PreServeFn func(inherited bool) error

	// PreShutdownFn is a common hook which notifies client that all servers are
	// about to start shutting down.
	PreShutdownFn func()

	// CompleteShutdownFn is a parent's hook, a part of shutdown process
	// that allows client to do extra work after all http servers will
	// be shutdown. All dependent resources can be closed here.
	//
	// For stateful services: and before child will start serving.
	CompleteShutdownFn func()

	// PreParentExitFn is a child's hook that allows client to do
	// extra work on a child's side before the parent will exit.
	//
	// Useful e.g. for updating pid in a pid file while acting
	// as a systemd's service.
	PreParentExitFn func()
	// contains filtered or unexported fields
}

App specifies functions to control passed HTTP servers.

func NewApp

func NewApp(servers ...*http.Server) *App

NewApp returns a new App instance.

func (*App) ListenAndServe added in v1.1.0

func (a *App) ListenAndServe() error

ListenAndServe creates listeners for the given servers or reuses the inherited ones. It also serves the servers and monitors OS signals.

func (*App) SetWaitChildTimeout added in v1.1.0

func (a *App) SetWaitChildTimeout(d time.Duration)

SetWaitChildTimeout sets the maximum amount of time for a parent to wait for a child when activation is started. It is reset whenever a new activation process is started.

When the timeout ends, the activating child will be killed with no regrets. The activation prosess will be stopped in this case.

There is only one reason to tune this timeout - if the app is starting for a long time.

Default value is 60 seconds.

func (*App) SetWaitParentShutdownTimeout added in v1.1.0

func (a *App) SetWaitParentShutdownTimeout(d time.Duration)

SetWaitParentShutdownTimeout sets the maximum amount of time for a child to wait for a parent shutdown when activation is started. It is reset whenever a new activation process is started.

When the timeout ends (if it is not 0), the activated child will kill his parent.

The timeout is usable for statefull services and basically describes maximum amount of time for a single request handling by a parent.

Default value is 0 that means no timeout. A child will start accepting new connections immediately.

func (*App) Shutdown added in v1.1.0

func (a *App) Shutdown()

Shutdown gracefully shut downs all servers without interrupting any active connections.

type StdLogger

type StdLogger interface {
	Print(...interface{})
	Printf(string, ...interface{})
	Println(...interface{})
}

StdLogger is an interface for stdlib logger also compatible with logrus

type StreamMessenger

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

StreamMessenger a simple messenger based on net.Conn. The simplest way to create messenger is to use syscall.Socketpair():

fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
f0 := os.NewFile(uintptr(fds[0]), "s|0")
f1 := os.NewFile(uintptr(fds[1]), "s|1")

m0, err := ListenSocket(f0)
m1, err := ListenSocket(f1)

Packet format: +-----------------------+---------+ | Header (8 bytes) | Payload | +-----------------------+---------+ | MagicN | Payload Size | Payload | +-----------------------+---------+

func ListenSocket

func ListenSocket(s *os.File) (*StreamMessenger, error)

ListenSocket TODO

func (*StreamMessenger) Close

func (m *StreamMessenger) Close() error

Close closes the connection. Any blocked Read or Write operations will be unblocked and return errors.

func (*StreamMessenger) Recv

func (m *StreamMessenger) Recv(v interface{}) (err error)

Recv receives a message from the channel.

func (*StreamMessenger) Send

func (m *StreamMessenger) Send(v interface{}) error

Send sends a message to the channel.

func (*StreamMessenger) SetDeadline

func (m *StreamMessenger) SetDeadline(t time.Time) error

SetDeadline sets the read and write deadlines associated with the connection. It is equivalent to calling both SetReadDeadline and SetWriteDeadline.

A deadline is an absolute time after which I/O operations fail with a timeout (see type Error) instead of blocking. The deadline applies to all future and pending I/O, not just the immediately following call to Read or Write. After a deadline has been exceeded, the connection can be refreshed by setting a deadline in the future.

An idle timeout can be implemented by repeatedly extending the deadline after successful Read or Write calls.

A zero value for t means I/O operations will not time out.

func (*StreamMessenger) SetReadDeadline

func (m *StreamMessenger) SetReadDeadline(t time.Time) error

SetReadDeadline sets the deadline for future Read calls and any currently-blocked Read call. A zero value for t means Read will not time out.

func (*StreamMessenger) SetWriteDeadline

func (m *StreamMessenger) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets the deadline for future Write calls and any currently-blocked Write call. Even if write times out, it may return n > 0, indicating that some of the data was successfully written. A zero value for t means Write will not time out.

Source Files

  • app.go
  • doc.go
  • exchange.go
  • file_listener.go
  • keep_alive_listener.go
  • listen_fds.go
  • logger.go
  • notify_listener.go
  • stream_messenger.go

Directories

Path Synopsis
examples
test command

Jump to

Keyboard shortcuts

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