-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
net: more detailed TCP keep-alive configuration #62254
Comments
I found the following survey of keep-alive behaviors to be useful: That post also covers the |
Presumably |
That was my thought. If a caller doesn't mind a platform not supporting an option, they can just not check the returned error. |
Maybe we should return an error that wraps |
This proposal has been added to the active column of the proposals project |
This seems reasonable, well-motivated, and well-justified. Thank you. It would help to say what the current defaults are in the config struct docs. And in Count maybe "should be sent" should be "can go unanswered". |
Updated proposal with the suggested changes. I needed to pick default values for KeepAliveConfig fields. I went with the current behavior for Idle and Interval (15 seconds), and the Linux kernel default for Count (9). We could also say that the default for Count matches the current behavior of picking the OS default, but it seems less surprising for us to set all three.
|
Based on the discussion above, this proposal seems like a likely accept. Proposal details are in #62254 (comment). |
No change in consensus, so accepted. 🎉 Proposal details are in #62254 (comment). |
I've done some investigations about TCP keep-alive on various platforms and had a CL for this proposal drafted, I'd volunteer to implement this if you don't mind. |
Change https://go.dev/cl/542275 mentions this issue: |
Thanks everyone for the discourse! Looks like it is too late in the cycle to get in, forward rolling to Go1.23. |
TCP keep-alives are enabled by setting the
SO_KEEPALIVE
socket option. When keep-alives are enabled, the operating system will probe idle connections and close connections with an unresponsive peer.Linux, FreeBSD, and Windows permit configuring keep-alive probes with the
TCP_KEEPIDLE
,TCP_KEEPINTVL
, andTCP_KEEPCNT
socket options. (Darwin appears to callTCP_KEEPIDLE
TCP_KEEPALIVE
.) These options set the idle duration before the first probe is sent, the interval between probes, and the maximum number of probes to send before declaring a connection dead, respectively.The
net
package permits configuring TCP keepalive behavior with:Dialer.KeepAlive
ListenConfig.KeepAlive
TCPConn.SetKeepAlive
TCPConn.SetKeepAlivePeriod
Setting the keep-alive period sets both
TCP_KEEPIDLE
andTCP_KEEPINTVL
. There is no way in thenet
package to setTCP_KEEPCNT
or otherwise configure how long it takes to declare a connection dead. There is no way to set different values for the idle period and the probe interval.Since Go 1.12 (https://go.dev/cl/107196), the
net
package has setTCP_KEEPIDLE
andTCP_KEEPINTVL
on all new sockets to 15 seconds by default.This 15 second value is not appropriate for all uses. For example, #48622 complains that the default keep-alive settings cause excessive CPU consumption on mobile devices due to frequent probes. Reducing the time until the first keep-alive probe is sent with
Dialer.KeepAlive
also reduces the time between probes; setting the period to five minutes will cause the kernel to take ~50 minutes to detect a dead connection.I propose that we change the
net
package functions which set the keep-alive period to setTCP_KEEPIDLE
, but notTCP_KEEPINTVL
. It is surprising and not useful for a "keep-alive period" of ten minutes to translate into a connection being declared dead only after several hours of unresponsiveness.I propose that we also add a finer-grained API for configuring keep-alive behavior. I haven't exhaustively surveyed the operating systems we support, but Linux, Windows, Darwin, and at least one BSD all appear to support the same three settings. It's possible to set these via
golang.org/x/sys
, but providing a common way to configure them in thenet
package seems reasonable.The following API also permits for enabling keep-alives on a connection while using the operating system default keep-alive configuration (set
KeepAliveConfig.Enable
, set the other fields to -1).The text was updated successfully, but these errors were encountered: