-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
What version of Go are you using (go version
)?
$ go version go version go1.20.1 linux/amd64
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/stephen/.cache/go-build" GOENV="/home/stephen/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/stephen/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/stephen/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.20.1" GCCGO="gccgo" GOAMD64="v1" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/dev/null" GOWORK="" CGO_CFLAGS="-O2 -g" CGO_CPPFLAGS="" CGO_CXXFLAGS="-O2 -g" CGO_FFLAGS="-O2 -g" CGO_LDFLAGS="-O2 -g" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build223210887=/tmp/go-build -gno-record-gcc-switches"
What did you do?
We added an explicit call to SetLinger(15)
here: ava-labs/avalanchego@1a2dca1
What did you expect to see?
Lines 161 to 173 in b94dc38
// SetLinger sets the behavior of Close on a connection which still | |
// has data waiting to be sent or to be acknowledged. | |
// | |
// If sec < 0 (the default), the operating system finishes sending the | |
// data in the background. | |
// | |
// If sec == 0, the operating system discards any unsent or | |
// unacknowledged data. | |
// | |
// If sec > 0, the data is sent in the background as with sec < 0. On | |
// some operating systems after sec seconds have elapsed any remaining | |
// unsent data may be discarded. | |
func (c *TCPConn) SetLinger(sec int) error { |
SetLinger
with a positive value will:
// If sec > 0, the data is sent in the background as with sec < 0. On
// some operating systems after sec seconds have elapsed any remaining
// unsent data may be discarded.
We expected for the OS to flush any outstanding data over the TCP stream in the background.
What did you see instead?
It doesn't seem that the data is being sent in the backaground, but that conn.Close()
may block until the specified timeout.
I don't think this is actually unexpected for the behavior of SO_LINGER:
SO_LINGER
Lingers on a close() if data is present. This option controls the action taken when unsent messages queue on a socket and close() is performed. If SO_LINGER is set, the system shall block the process during close() until it can transmit the data or until the time expires. If SO_LINGER is not specified, and close() is issued, the system handles the call in a way that allows the process to continue as quickly as possible. This option takes a linger structure, as defined in the <sys/socket.h> header, to specify the state of the option and linger interval.
However, I feel like the comment on SetLinger
seems to contradict the man pages.