https://github.com/gobwas/graceful
A library for graceful restarts in Go.
https://github.com/gobwas/graceful
golang graceful
Last synced: about 1 month ago
JSON representation
A library for graceful restarts in Go.
- Host: GitHub
- URL: https://github.com/gobwas/graceful
- Owner: gobwas
- License: mit
- Created: 2017-05-03T08:58:38.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2017-11-10T10:04:58.000Z (over 7 years ago)
- Last Synced: 2025-03-18T08:11:18.712Z (about 1 month ago)
- Topics: golang, graceful
- Language: Go
- Homepage:
- Size: 198 KB
- Stars: 94
- Watchers: 3
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Graceful 💎
[![GoDoc][godoc-image]][godoc-url]
[![Travis][travis-image]][travis-url]> A library for sharing descriptors in Go.
# Overview
Package graceful provides tools for sharing file descriptors between processes.
The most common reason to use it is the ability of so-called **graceful
restart** of an application.There is an [example web application](example) that restarts gracefully.
# Usage
Graceful proposes a client-server mechanism of sharing file descriptors.
That is, application that owns a descriptors is a **server** in `graceful`
terminology, and an application that wants to receive those descriptors is a
**client**.The most common use of `graceful` looks like this:
```go
// Somewhere close to the application initialization.
//
// By some logic we've decided to receive descriptors from currently running
// instance of the application.
var (
ln net.Listener
file *os.File
)
err := graceful.Receive("/var/run/app.sock", func(fd int, meta io.Reader) error {
// Handle received descriptor with concrete application logic.
//
// meta is an additional information that corresponds to the descriptor and
// represented by an io.Reader. User is free to select strategy of
// marshaling/unmarshaling this information.
if meta == nil {
// In our example listener is passed with empty meta.
ln = graceful.FdListener(fd)
return nil
}
// There is a helper type called graceful.Meta that could be used to send
// key-value pairs of meta without additional lines of code. Lets use it.
m := new(graceful.Meta)
if _, err := m.ReadFrom(meta); err != nil {
// Prevent further interaction with the connection due to the error.
return err
}
file = os.NewFile(fd, m["name"])
})
if err != nil {
// Handle error.
}...
// Somewhere close to the application termination.
//
// By some logic we've decided to send our descriptors to a new application
// instance that is probably just started.
//
// This code will send `ln` and `file` descriptors to every accepted
// connection on unix domain socket "/var/run/app.sock".
go graceful.ListenAndServe("/var/run/app.sock", graceful.SequenceHandler(
graceful.ListenerHandler(ln, nil),
graceful.FileHandler(file, graceful.Meta{
"name": file.Name(),
}),
))
```That is, `graceful` does not force users to stick to some logic of processing
restarts. It just provides mechanism for sharing descriptors in a client-server
way.If you have a more difficult logic of restarts, you could use less general API
of `graceful`:```go
// Listen for an upcoming instance at the socket.
ln, err := net.Listen("unix", "/var/run/app.sock")
if err != nil {
// Handle error.
}
defer ln.Close()// Accept client connection from another application instance.
conn, err := ln.Accept()
if err != nil {
// Handle error.
}
defer conn.Close()// Send some application specific data first. This is useful when data is much
// larger than graceful i/o buffers and won't be putted in the descriptor meta.
if _, err := conn.Write(data); err != nil {
// Handle error.
}// Then send some descriptors to the connection.
graceful.SendListenerTo(conn, ln, nil)
graceful.SendListenerTo(conn, file, graceful.Meta{
"name": file.Name(),
})// Alternatively, you could send custom meta information with the fd.
//
// bytes.Buffer instance implements io.WriterTo, so wa are free to use it as
// meta argument for graceful.Send*() calls.
buf := new(bytes.Buffer)
buf.Write("Hello, I am meta!")// Now send some descriptor with custom meta bytes.
// Client will receive io.Reader instance as meta that contains our simple
// string.
graceful.SendTo(conn, someFD, buf)
```There is an [example web application](example) that handles restarts
gracefully. Note that it does not handle `SIGTERM` signal just to show up that
`graceful` if flexible and could be used in a simple way.# Status
This library is not tagged as stable version (and not tagged at all yet).
This means that backward compatibility can be broken due some changes or
refactoring.[sigterm]: https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
[example]: https://github.com/gobwas/graceful/tree/master/example
[godoc-image]: https://godoc.org/github.com/gobwas/graceful?status.svg
[godoc-url]: https://godoc.org/github.com/gobwas/graceful
[travis-image]: https://travis-ci.org/gobwas/graceful.svg?branch=master
[travis-url]: https://travis-ci.org/gobwas/graceful