mirror of
https://github.com/minio/minio.git
synced 2025-01-23 12:43:16 -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.IdleTimeout = ctx.Duration("idle-timeout")
|
||||
ctxt.UserTimeout = ctx.Duration("conn-user-timeout")
|
||||
ctxt.ShutdownTimeout = ctx.Duration("shutdown-timeout")
|
||||
|
||||
if conf := ctx.String("config"); len(conf) > 0 {
|
||||
err = mergeServerCtxtFromConfigFile(conf, ctxt)
|
||||
|
@ -163,7 +163,6 @@ type serverCtxt struct {
|
||||
MemLimit uint64
|
||||
|
||||
UserTimeout time.Duration
|
||||
ShutdownTimeout time.Duration
|
||||
IdleTimeout time.Duration
|
||||
ReadHeaderTimeout time.Duration
|
||||
MaxIdleConnsPerHost int
|
||||
|
@ -84,11 +84,12 @@ var ServerFlags = []cli.Flag{
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "shutdown-timeout",
|
||||
Value: xhttp.DefaultShutdownTimeout,
|
||||
Usage: "shutdown timeout to gracefully shutdown server",
|
||||
Value: time.Second * 30,
|
||||
Usage: "shutdown timeout to gracefully shutdown server (DEPRECATED)",
|
||||
EnvVar: "MINIO_SHUTDOWN_TIMEOUT",
|
||||
Hidden: true,
|
||||
},
|
||||
|
||||
cli.DurationFlag{
|
||||
Name: "idle-timeout",
|
||||
Value: xhttp.DefaultIdleTimeout,
|
||||
@ -866,7 +867,6 @@ func serverMain(ctx *cli.Context) {
|
||||
httpServer := xhttp.NewServer(getServerListenAddrs()).
|
||||
UseHandler(setCriticalErrorHandler(corsHandler(handler))).
|
||||
UseTLSConfig(newTLSConfig(getCert)).
|
||||
UseShutdownTimeout(globalServerCtxt.ShutdownTimeout).
|
||||
UseIdleTimeout(globalServerCtxt.IdleTimeout).
|
||||
UseReadHeaderTimeout(globalServerCtxt.ReadHeaderTimeout).
|
||||
UseBaseContext(GlobalContext).
|
||||
|
@ -22,11 +22,8 @@ import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -43,11 +40,6 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
shutdownPollIntervalMax = 500 * time.Millisecond
|
||||
|
||||
// DefaultShutdownTimeout - default shutdown timeout to gracefully shutdown server.
|
||||
DefaultShutdownTimeout = 5 * time.Second
|
||||
|
||||
// DefaultIdleTimeout for idle inactive connections
|
||||
DefaultIdleTimeout = 30 * time.Second
|
||||
|
||||
@ -61,13 +53,12 @@ const (
|
||||
// Server - extended http.Server supports multiple addresses to serve and enhanced connection handling.
|
||||
type Server struct {
|
||||
http.Server
|
||||
Addrs []string // addresses on which the server listens for new connection.
|
||||
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.
|
||||
listener *httpListener // HTTP listener for all 'Addrs' field.
|
||||
inShutdown uint32 // indicates whether the server is in shutdown or not
|
||||
requestCount int32 // counter holds no. of request in progress.
|
||||
Addrs []string // addresses on which the server listens for new connection.
|
||||
TCPOptions TCPOptions // all the configurable TCP conn specific configurable options.
|
||||
listenerMutex sync.Mutex // to guard 'listener' field.
|
||||
listener *httpListener // HTTP listener for all 'Addrs' field.
|
||||
inShutdown uint32 // indicates whether the server is in shutdown or not
|
||||
requestCount int32 // counter holds no. of request in progress.
|
||||
}
|
||||
|
||||
// GetRequestCount - returns number of request in progress.
|
||||
@ -166,53 +157,8 @@ func (srv *Server) Shutdown() error {
|
||||
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.
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
return nil
|
||||
}
|
||||
|
||||
// UseIdleTimeout configure idle connection timeout
|
||||
|
@ -48,8 +48,7 @@ func TestNewServer(t *testing.T) {
|
||||
|
||||
for i, testCase := range testCases {
|
||||
server := NewServer(testCase.addrs).
|
||||
UseHandler(testCase.handler).
|
||||
UseShutdownTimeout(DefaultShutdownTimeout)
|
||||
UseHandler(testCase.handler)
|
||||
if testCase.certFn != nil {
|
||||
server = server.UseTLSConfig(&tls.Config{
|
||||
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 {
|
||||
t.Fatalf("Case %v: server.MaxHeaderBytes: expected: %v, got: %v", (i + 1), DefaultMaxHeaderBytes, server.MaxHeaderBytes)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user