mirror of
https://github.com/minio/minio.git
synced 2025-02-03 01:46:00 -05:00
Removing timeout on shutdown (#19956)
This commit is contained in:
parent
7a4b250c8b
commit
bce93b5cfa
@ -433,7 +433,6 @@ func buildServerCtxt(ctx *cli.Context, ctxt *serverCtxt) (err error) {
|
|||||||
ctxt.RecvBufSize = ctx.Int("recv-buf-size")
|
ctxt.RecvBufSize = ctx.Int("recv-buf-size")
|
||||||
ctxt.IdleTimeout = ctx.Duration("idle-timeout")
|
ctxt.IdleTimeout = ctx.Duration("idle-timeout")
|
||||||
ctxt.UserTimeout = ctx.Duration("conn-user-timeout")
|
ctxt.UserTimeout = ctx.Duration("conn-user-timeout")
|
||||||
ctxt.ShutdownTimeout = ctx.Duration("shutdown-timeout")
|
|
||||||
|
|
||||||
if conf := ctx.String("config"); len(conf) > 0 {
|
if conf := ctx.String("config"); len(conf) > 0 {
|
||||||
err = mergeServerCtxtFromConfigFile(conf, ctxt)
|
err = mergeServerCtxtFromConfigFile(conf, ctxt)
|
||||||
|
@ -163,7 +163,6 @@ type serverCtxt struct {
|
|||||||
MemLimit uint64
|
MemLimit uint64
|
||||||
|
|
||||||
UserTimeout time.Duration
|
UserTimeout time.Duration
|
||||||
ShutdownTimeout time.Duration
|
|
||||||
IdleTimeout time.Duration
|
IdleTimeout time.Duration
|
||||||
ReadHeaderTimeout time.Duration
|
ReadHeaderTimeout time.Duration
|
||||||
MaxIdleConnsPerHost int
|
MaxIdleConnsPerHost int
|
||||||
|
@ -84,11 +84,12 @@ var ServerFlags = []cli.Flag{
|
|||||||
},
|
},
|
||||||
cli.DurationFlag{
|
cli.DurationFlag{
|
||||||
Name: "shutdown-timeout",
|
Name: "shutdown-timeout",
|
||||||
Value: xhttp.DefaultShutdownTimeout,
|
Value: time.Second * 30,
|
||||||
Usage: "shutdown timeout to gracefully shutdown server",
|
Usage: "shutdown timeout to gracefully shutdown server (DEPRECATED)",
|
||||||
EnvVar: "MINIO_SHUTDOWN_TIMEOUT",
|
EnvVar: "MINIO_SHUTDOWN_TIMEOUT",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
cli.DurationFlag{
|
cli.DurationFlag{
|
||||||
Name: "idle-timeout",
|
Name: "idle-timeout",
|
||||||
Value: xhttp.DefaultIdleTimeout,
|
Value: xhttp.DefaultIdleTimeout,
|
||||||
@ -866,7 +867,6 @@ func serverMain(ctx *cli.Context) {
|
|||||||
httpServer := xhttp.NewServer(getServerListenAddrs()).
|
httpServer := xhttp.NewServer(getServerListenAddrs()).
|
||||||
UseHandler(setCriticalErrorHandler(corsHandler(handler))).
|
UseHandler(setCriticalErrorHandler(corsHandler(handler))).
|
||||||
UseTLSConfig(newTLSConfig(getCert)).
|
UseTLSConfig(newTLSConfig(getCert)).
|
||||||
UseShutdownTimeout(globalServerCtxt.ShutdownTimeout).
|
|
||||||
UseIdleTimeout(globalServerCtxt.IdleTimeout).
|
UseIdleTimeout(globalServerCtxt.IdleTimeout).
|
||||||
UseReadHeaderTimeout(globalServerCtxt.ReadHeaderTimeout).
|
UseReadHeaderTimeout(globalServerCtxt.ReadHeaderTimeout).
|
||||||
UseBaseContext(GlobalContext).
|
UseBaseContext(GlobalContext).
|
||||||
|
@ -22,11 +22,8 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"runtime/pprof"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -43,11 +40,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
shutdownPollIntervalMax = 500 * time.Millisecond
|
|
||||||
|
|
||||||
// DefaultShutdownTimeout - default shutdown timeout to gracefully shutdown server.
|
|
||||||
DefaultShutdownTimeout = 5 * time.Second
|
|
||||||
|
|
||||||
// DefaultIdleTimeout for idle inactive connections
|
// DefaultIdleTimeout for idle inactive connections
|
||||||
DefaultIdleTimeout = 30 * time.Second
|
DefaultIdleTimeout = 30 * time.Second
|
||||||
|
|
||||||
@ -63,7 +55,6 @@ type Server struct {
|
|||||||
http.Server
|
http.Server
|
||||||
Addrs []string // addresses on which the server listens for new connection.
|
Addrs []string // addresses on which the server listens for new connection.
|
||||||
TCPOptions TCPOptions // all the configurable TCP conn specific configurable options.
|
TCPOptions TCPOptions // all the configurable TCP conn specific configurable options.
|
||||||
ShutdownTimeout time.Duration // timeout used for graceful server shutdown.
|
|
||||||
listenerMutex sync.Mutex // to guard 'listener' field.
|
listenerMutex sync.Mutex // to guard 'listener' field.
|
||||||
listener *httpListener // HTTP listener for all 'Addrs' field.
|
listener *httpListener // HTTP listener for all 'Addrs' field.
|
||||||
inShutdown uint32 // indicates whether the server is in shutdown or not
|
inShutdown uint32 // indicates whether the server is in shutdown or not
|
||||||
@ -166,53 +157,8 @@ func (srv *Server) Shutdown() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pollIntervalBase := time.Millisecond
|
|
||||||
nextPollInterval := func() time.Duration {
|
|
||||||
// Add 10% jitter.
|
|
||||||
interval := pollIntervalBase + time.Duration(rand.Intn(int(pollIntervalBase/10)))
|
|
||||||
// Double and clamp for next time.
|
|
||||||
pollIntervalBase *= 2
|
|
||||||
if pollIntervalBase > shutdownPollIntervalMax {
|
|
||||||
pollIntervalBase = shutdownPollIntervalMax
|
|
||||||
}
|
|
||||||
return interval
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for opened connection to be closed up to Shutdown timeout.
|
// Wait for opened connection to be closed up to Shutdown timeout.
|
||||||
shutdownTimeout := srv.ShutdownTimeout
|
|
||||||
shutdownTimer := time.NewTimer(shutdownTimeout)
|
|
||||||
defer shutdownTimer.Stop()
|
|
||||||
|
|
||||||
timer := time.NewTimer(nextPollInterval())
|
|
||||||
defer timer.Stop()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-shutdownTimer.C:
|
|
||||||
if atomic.LoadInt32(&srv.requestCount) <= 0 {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
|
||||||
|
|
||||||
// Write all running goroutines.
|
|
||||||
tmp, err := os.CreateTemp("", "minio-goroutines-*.txt")
|
|
||||||
if err == nil {
|
|
||||||
_ = pprof.Lookup("goroutine").WriteTo(tmp, 1)
|
|
||||||
tmp.Close()
|
|
||||||
return errors.New("timed out. some connections are still active. goroutines written to " + tmp.Name())
|
|
||||||
}
|
|
||||||
return errors.New("timed out. some connections are still active")
|
|
||||||
case <-timer.C:
|
|
||||||
if atomic.LoadInt32(&srv.requestCount) <= 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
timer.Reset(nextPollInterval())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UseShutdownTimeout configure server shutdown timeout
|
|
||||||
func (srv *Server) UseShutdownTimeout(d time.Duration) *Server {
|
|
||||||
srv.ShutdownTimeout = d
|
|
||||||
return srv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UseIdleTimeout configure idle connection timeout
|
// UseIdleTimeout configure idle connection timeout
|
||||||
|
@ -48,8 +48,7 @@ func TestNewServer(t *testing.T) {
|
|||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
server := NewServer(testCase.addrs).
|
server := NewServer(testCase.addrs).
|
||||||
UseHandler(testCase.handler).
|
UseHandler(testCase.handler)
|
||||||
UseShutdownTimeout(DefaultShutdownTimeout)
|
|
||||||
if testCase.certFn != nil {
|
if testCase.certFn != nil {
|
||||||
server = server.UseTLSConfig(&tls.Config{
|
server = server.UseTLSConfig(&tls.Config{
|
||||||
PreferServerCipherSuites: true,
|
PreferServerCipherSuites: true,
|
||||||
@ -72,10 +71,6 @@ func TestNewServer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if server.ShutdownTimeout != DefaultShutdownTimeout {
|
|
||||||
t.Fatalf("Case %v: server.ShutdownTimeout: expected: %v, got: %v", (i + 1), DefaultShutdownTimeout, server.ShutdownTimeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
if server.MaxHeaderBytes != DefaultMaxHeaderBytes {
|
if server.MaxHeaderBytes != DefaultMaxHeaderBytes {
|
||||||
t.Fatalf("Case %v: server.MaxHeaderBytes: expected: %v, got: %v", (i + 1), DefaultMaxHeaderBytes, server.MaxHeaderBytes)
|
t.Fatalf("Case %v: server.MaxHeaderBytes: expected: %v, got: %v", (i + 1), DefaultMaxHeaderBytes, server.MaxHeaderBytes)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user