mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-13 22:36:27 +03:00
core: Eliminate unnecessary shutdown delay on Unix (#5413)
* core: Eliminate unnecessary shutdown delay on Unix Fix #5393, alternate to #5405 * Comments, cleanup, adjust logs * Fix build constraint
This commit is contained in:
parent
85375861f6
commit
99d47050e9
4 changed files with 36 additions and 13 deletions
2
go.mod
2
go.mod
|
@ -1,6 +1,6 @@
|
||||||
module github.com/caddyserver/caddy/v2
|
module github.com/caddyserver/caddy/v2
|
||||||
|
|
||||||
go 1.18
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.2.1
|
github.com/BurntSushi/toml v1.2.1
|
||||||
|
|
|
@ -12,10 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// TODO: Go 1.19 introduced the "unix" build tag. We have to support Go 1.18 until Go 1.20 is released.
|
//go:build !unix
|
||||||
// When Go 1.19 is our minimum, change this build tag to simply "!unix".
|
|
||||||
// (see similar change needed in listen_unix.go)
|
|
||||||
//go:build !(aix || android || darwin || dragonfly || freebsd || hurd || illumos || ios || linux || netbsd || openbsd || solaris)
|
|
||||||
|
|
||||||
package caddy
|
package caddy
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// TODO: Go 1.19 introduced the "unix" build tag. We have to support Go 1.18 until Go 1.20 is released.
|
// Even though the filename ends in _unix.go, we still have to specify the
|
||||||
// When Go 1.19 is our minimum, remove this build tag, since "_unix" in the filename will do this.
|
// build constraint here, because the filename convention only works for
|
||||||
// (see also change needed in listen.go)
|
// literal GOOS values, and "unix" is a shortcut unique to build tags.
|
||||||
//go:build aix || android || darwin || dragonfly || freebsd || hurd || illumos || ios || linux || netbsd || openbsd || solaris
|
//go:build unix
|
||||||
|
|
||||||
package caddy
|
package caddy
|
||||||
|
|
||||||
|
@ -98,7 +98,19 @@ func listenTCPOrUnix(ctx context.Context, lnKey string, network, address string,
|
||||||
}
|
}
|
||||||
return reusePort(network, address, c)
|
return reusePort(network, address, c)
|
||||||
}
|
}
|
||||||
return config.Listen(ctx, network, address)
|
|
||||||
|
// even though SO_REUSEPORT lets us bind the socket multiple times,
|
||||||
|
// we still put it in the listenerPool so we can count how many
|
||||||
|
// configs are using this socket; necessary to ensure we can know
|
||||||
|
// whether to enforce shutdown delays, for example (see #5393).
|
||||||
|
ln, err := config.Listen(ctx, network, address)
|
||||||
|
if err == nil {
|
||||||
|
listenerPool.LoadOrStore(lnKey, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// lightly wrap the listener so that when it is closed,
|
||||||
|
// we can decrement the usage pool counter
|
||||||
|
return deleteListener{ln, lnKey}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// reusePort sets SO_REUSEPORT. Ineffective for unix sockets.
|
// reusePort sets SO_REUSEPORT. Ineffective for unix sockets.
|
||||||
|
@ -116,3 +128,17 @@ func reusePort(network, address string, conn syscall.RawConn) error {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteListener is a type that simply deletes itself
|
||||||
|
// from the listenerPool when it closes. It is used
|
||||||
|
// solely for the purpose of reference counting (i.e.
|
||||||
|
// counting how many configs are using a given socket).
|
||||||
|
type deleteListener struct {
|
||||||
|
net.Listener
|
||||||
|
lnKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dl deleteListener) Close() error {
|
||||||
|
_, _ = listenerPool.Delete(dl.lnKey)
|
||||||
|
return dl.Listener.Close()
|
||||||
|
}
|
||||||
|
|
|
@ -517,7 +517,7 @@ func (app *App) Stop() error {
|
||||||
|
|
||||||
// honor scheduled/delayed shutdown time
|
// honor scheduled/delayed shutdown time
|
||||||
if delay {
|
if delay {
|
||||||
app.logger.Debug("shutdown scheduled",
|
app.logger.Info("shutdown scheduled",
|
||||||
zap.Duration("delay_duration", time.Duration(app.ShutdownDelay)),
|
zap.Duration("delay_duration", time.Duration(app.ShutdownDelay)),
|
||||||
zap.Time("time", scheduledTime))
|
zap.Time("time", scheduledTime))
|
||||||
time.Sleep(time.Duration(app.ShutdownDelay))
|
time.Sleep(time.Duration(app.ShutdownDelay))
|
||||||
|
@ -528,9 +528,9 @@ func (app *App) Stop() error {
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
ctx, cancel = context.WithTimeout(ctx, time.Duration(app.GracePeriod))
|
ctx, cancel = context.WithTimeout(ctx, time.Duration(app.GracePeriod))
|
||||||
defer cancel()
|
defer cancel()
|
||||||
app.logger.Debug("servers shutting down; grace period initiated", zap.Duration("duration", time.Duration(app.GracePeriod)))
|
app.logger.Info("servers shutting down; grace period initiated", zap.Duration("duration", time.Duration(app.GracePeriod)))
|
||||||
} else {
|
} else {
|
||||||
app.logger.Debug("servers shutting down with eternal grace period")
|
app.logger.Info("servers shutting down with eternal grace period")
|
||||||
}
|
}
|
||||||
|
|
||||||
// goroutines aren't guaranteed to be scheduled right away,
|
// goroutines aren't guaranteed to be scheduled right away,
|
||||||
|
|
Loading…
Reference in a new issue