@marcel91200 / caddy Mirror · read-only / commits / 99d47050
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 05:30 UTC

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

Matt Holt committed Mar 2, 2023 at 21:00 UTC 99d47050e97a8ccac2aad3bda46be46d4fec85ed
4 files changed +36 -13
go.mod
+1 -1
@@ -1,6 +1,6 @@
1 module github.com/caddyserver/caddy/v2
2
3 -go 1.18
3 +go 1.19
4
5 require (
6 github.com/BurntSushi/toml v1.2.1
listen.go
+1 -4
@@ -12,10 +12,7 @@
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 -// TODO: Go 1.19 introduced the "unix" build tag. We have to support Go 1.18 until Go 1.20 is released.
16 -// When Go 1.19 is our minimum, change this build tag to simply "!unix".
17 -// (see similar change needed in listen_unix.go)
18 -//go:build !(aix || android || darwin || dragonfly || freebsd || hurd || illumos || ios || linux || netbsd || openbsd || solaris)
15 +//go:build !unix
16
17 package caddy
18
listen_unix.go
+31 -5
@@ -12,10 +12,10 @@
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 -// TODO: Go 1.19 introduced the "unix" build tag. We have to support Go 1.18 until Go 1.20 is released.
16 -// When Go 1.19 is our minimum, remove this build tag, since "_unix" in the filename will do this.
17 -// (see also change needed in listen.go)
18 -//go:build aix || android || darwin || dragonfly || freebsd || hurd || illumos || ios || linux || netbsd || openbsd || solaris
15 +// Even though the filename ends in _unix.go, we still have to specify the
16 +// build constraint here, because the filename convention only works for
17 +// literal GOOS values, and "unix" is a shortcut unique to build tags.
18 +//go:build unix
19
20 package caddy
21
@@ -98,7 +98,19 @@ func listenTCPOrUnix(ctx context.Context, lnKey string, network, address string,
98 }
99 return reusePort(network, address, c)
100 }
101 - return config.Listen(ctx, network, address)
101 +
102 + // even though SO_REUSEPORT lets us bind the socket multiple times,
103 + // we still put it in the listenerPool so we can count how many
104 + // configs are using this socket; necessary to ensure we can know
105 + // whether to enforce shutdown delays, for example (see #5393).
106 + ln, err := config.Listen(ctx, network, address)
107 + if err == nil {
108 + listenerPool.LoadOrStore(lnKey, nil)
109 + }
110 +
111 + // lightly wrap the listener so that when it is closed,
112 + // we can decrement the usage pool counter
113 + return deleteListener{ln, lnKey}, err
114 }
115
116 // reusePort sets SO_REUSEPORT. Ineffective for unix sockets.
@@ -116,3 +128,17 @@ func reusePort(network, address string, conn syscall.RawConn) error {
128 }
129 })
130 }
131 +
132 +// deleteListener is a type that simply deletes itself
133 +// from the listenerPool when it closes. It is used
134 +// solely for the purpose of reference counting (i.e.
135 +// counting how many configs are using a given socket).
136 +type deleteListener struct {
137 + net.Listener
138 + lnKey string
139 +}
140 +
141 +func (dl deleteListener) Close() error {
142 + _, _ = listenerPool.Delete(dl.lnKey)
143 + return dl.Listener.Close()
144 +}
modules/caddyhttp/app.go
+3 -3
@@ -517,7 +517,7 @@ func (app *App) Stop() error {
517
518 // honor scheduled/delayed shutdown time
519 if delay {
520 - app.logger.Debug("shutdown scheduled",
520 + app.logger.Info("shutdown scheduled",
521 zap.Duration("delay_duration", time.Duration(app.ShutdownDelay)),
522 zap.Time("time", scheduledTime))
523 time.Sleep(time.Duration(app.ShutdownDelay))
@@ -528,9 +528,9 @@ func (app *App) Stop() error {
528 var cancel context.CancelFunc
529 ctx, cancel = context.WithTimeout(ctx, time.Duration(app.GracePeriod))
530 defer cancel()
531 - app.logger.Debug("servers shutting down; grace period initiated", zap.Duration("duration", time.Duration(app.GracePeriod)))
531 + app.logger.Info("servers shutting down; grace period initiated", zap.Duration("duration", time.Duration(app.GracePeriod)))
532 } else {
533 - app.logger.Debug("servers shutting down with eternal grace period")
533 + app.logger.Info("servers shutting down with eternal grace period")
534 }
535
536 // goroutines aren't guaranteed to be scheduled right away,