Documentation ¶
Overview ¶
Example (HttpShutdown) ¶
This shows how to use the upgrader with the graceful shutdown facilities of net/http.
package main import ( "context" "flag" "fmt" upgrader "github.com/iamxvbaba/server/upgrader" "log" "net/http" "os" "os/signal" "syscall" "time" ) func main() { var ( listenAddr = flag.String("listen", "localhost:8080", "`Address` to listen on") pidFile = flag.String("pid-file", "", "`Path` to pid file") ) flag.Parse() log.SetPrefix(fmt.Sprintf("%d ", os.Getpid())) upg, err := upgrader.New(upgrader.Options{ PIDFile: *pidFile, }) if err != nil { panic(err) } defer upg.Stop() // Do an upgrade on SIGHUP go func() { sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGHUP) for range sig { err := upg.Upgrade() if err != nil { log.Println("Upgrade failed:", err) } } }() // Listen must be called before Ready ln, err := upg.Listen("tcp", *listenAddr) if err != nil { log.Fatalln("Can't listen:", err) } server := http.Server{ // Set timeouts, etc. } go func() { err := server.Serve(ln) if err != http.ErrServerClosed { log.Println("HTTP server:", err) } }() log.Printf("ready") if err := upg.Ready(); err != nil { panic(err) } <-upg.Exit() // Make sure to set a deadline on exiting the process // after upg.Exit() is closed. No new upgrades can be // performed if the parent doesn't exit. time.AfterFunc(30*time.Second, func() { log.Println("Graceful shutdown timed out") os.Exit(1) }) // Wait for connections to drain. server.Shutdown(context.Background()) }
Output:
Example (TcpServer) ¶
This shows how to use the Upgrader with a listener based service.
package main import ( "flag" "fmt" upgrader "github.com/iamxvbaba/server/upgrader" "log" "os" "os/signal" "syscall" "time" ) func main() { var ( listenAddr = flag.String("listen", "localhost:8080", "`Address` to listen on") pidFile = flag.String("pid-file", "", "`Path` to pid file") ) flag.Parse() log.SetPrefix(fmt.Sprintf("%d ", os.Getpid())) upg, err := upgrader.New(upgrader.Options{ PIDFile: *pidFile, }) if err != nil { panic(err) } defer upg.Stop() // Do an upgrade on SIGHUP go func() { sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGHUP) for range sig { err := upg.Upgrade() if err != nil { log.Println("upgrade failed:", err) } } }() ln, err := upg.Fds.Listen("tcp", *listenAddr) if err != nil { log.Fatalln("Can't listen:", err) } go func() { defer ln.Close() log.Printf("listening on %s", ln.Addr()) for { c, err := ln.Accept() if err != nil { return } go func() { c.SetDeadline(time.Now().Add(time.Second)) c.Write([]byte("It is a mistake to think you can solve any major problems just with potatoes.\n")) c.Close() }() } }() log.Printf("ready") if err := upg.Ready(); err != nil { panic(err) } <-upg.Exit() }
Output:
Index ¶
- Constants
- Variables
- type Conn
- type Fds
- func (f *Fds) AddConn(network, addr string, conn Conn) error
- func (f *Fds) AddFile(name string, file *os.File) error
- func (f *Fds) AddListener(network, addr string, ln Listener) error
- func (f *Fds) AddPacketConn(network, addr string, conn PacketConn) error
- func (f *Fds) Conn(network, addr string) (net.Conn, error)
- func (f *Fds) File(name string) (*os.File, error)
- func (f *Fds) Listen(network, addr string) (net.Listener, error)
- func (f *Fds) ListenPacket(network, addr string) (net.PacketConn, error)
- func (f *Fds) ListenPacketWithCallback(network, addr string, ...) (net.PacketConn, error)
- func (f *Fds) ListenWithCallback(network, addr string, ...) (net.Listener, error)
- func (f *Fds) Listener(network, addr string) (net.Listener, error)
- func (f *Fds) PacketConn(network, addr string) (net.PacketConn, error)
- type Listener
- type Options
- type PacketConn
- type Upgrader
Examples ¶
Constants ¶
const DefaultUpgradeTimeout time.Duration = time.Minute
DefaultUpgradeTimeout is the duration before the Upgrader kills the new process if no readiness notification was received.
Variables ¶
var ErrNotSupported = errors.New("upgrader: platform does not support graceful restart")
Functions ¶
This section is empty.
Types ¶
type Fds ¶
type Fds struct {
// contains filtered or unexported fields
}
Fds 保留从父进程继承的所有文件描述符。
func (*Fds) AddConn ¶
AddConn adds a connection.
It is safe to close conn after calling this method.
func (*Fds) AddListener ¶
AddListener adds a listener.
It is safe to close ln after calling the method. Any existing listener with the same address is overwitten.
func (*Fds) AddPacketConn ¶
func (f *Fds) AddPacketConn(network, addr string, conn PacketConn) error
AddPacketConn adds a PacketConn.
It is safe to close conn after calling the method. Any existing packet connection with the same address is overwitten.
func (*Fds) Conn ¶
Conn returns an inherited connection or nil.
It is safe to close the returned Conn.
func (*Fds) ListenPacket ¶
func (f *Fds) ListenPacket(network, addr string) (net.PacketConn, error)
ListenPacket returns a packet conn inherited from the parent process, or creates a new one.
func (*Fds) ListenPacketWithCallback ¶
func (f *Fds) ListenPacketWithCallback(network, addr string, callback func(network, addr string) (net.PacketConn, error)) (net.PacketConn, error)
ListenPacketWithCallback returns a packet conn inherited from the parent process, or calls the supplied callback to create a new one.
This should be used in case some customization has to be applied to create the connection. Note that the callback must not use the underlying `Fds` object as it will be locked during the call.
func (*Fds) ListenWithCallback ¶
func (f *Fds) ListenWithCallback(network, addr string, callback func(network, addr string) (net.Listener, error)) (net.Listener, error)
ListenWithCallback 返回从父进程继承的侦听器,或调用提供的回调来创建一个新的侦听器。 如果必须应用某些自定义来创建连接,则应使用此方法。请注意,callback时不得使用基础的 Fds 对象,因为它将在调用过程中被锁定。
func (*Fds) Listener ¶
Listener returns an inherited listener or nil.
It is safe to close the returned listener.
func (*Fds) PacketConn ¶
func (f *Fds) PacketConn(network, addr string) (net.PacketConn, error)
PacketConn returns an inherited packet connection or nil.
It is safe to close the returned packet connection.
type Options ¶
type Options struct { // Time after which an upgrade is considered failed. Defaults to // DefaultUpgradeTimeout. UpgradeTimeout time.Duration // The PID of a ready process is written to this file. PIDFile string // ListenConfig is a custom ListenConfig. Defaults to an empty ListenConfig ListenConfig *net.ListenConfig }
Options control the behaviour of the Upgrader.
type PacketConn ¶
type PacketConn interface { net.PacketConn syscall.Conn }
PacketConn can be shared between processes.
type Upgrader ¶
type Upgrader struct { *Fds // contains filtered or unexported fields }
Upgrader handles zero downtime upgrades and passing files between processes.
func (*Upgrader) Exit ¶
func (u *Upgrader) Exit() <-chan struct{}
Exit returns a channel which is closed when the process should exit.
func (*Upgrader) HasParent ¶
HasParent checks if the current process is an upgrade or the first invocation.
func (*Upgrader) Stop ¶
func (u *Upgrader) Stop()
Stop prevents any more upgrades from happening, and closes the exit channel.
If this function is called before a call to Upgrade() has succeeded, it is assumed that the process is being shut down completely. All Unix sockets known to Upgrader.Fds are then unlinked from the filesystem.