-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
How to handle TCP keepalive-related configurations more effectively? #1836
base: master
Are you sure you want to change the base?
How to handle TCP keepalive-related configurations more effectively? #1836
Conversation
createTcpListener_new.go
Outdated
@@ -0,0 +1,10 @@ | |||
//go:build go1.23 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can already see us forgetting to update this when a new version of Go is release (like we did here: https://github.com/search?q=repo%3Avalyala%2Ffasthttp+%22go%3Abuild+go1.20%22&type=code). I think it would be better to do this:
//go:build !go1.19 && !go1.20 && !go1.21 && !go1.22
That would automatically make it work for a future go1.24 etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I misunderstood. Go 1.23 did not change the default behavior of net.ListenConfig. If the KeepAlive field is 0, TCP keepalive will still be enabled. The new KeepAliveConfig just provides more granular control. To disable the keepalive mechanism, you still need to set the KeepAlive field to a negative value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current build tags for Go versions seem to be correct(b2s and s2b functions). I found a related question on Stack Overflow.
Golang build tags for a particular Go version possible?
Put the code that depends on contexts in a file with the following build tag. This code is compiled for Go 1.7 and onward.
// +build go1.7
Put the backwards compatibility code in a file with the following build tag. This code is used for all versions of Go before 1.7.
// +build !go1.7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I learned something new there.
bb7af24
to
f0a752c
Compare
Currently, when Server.TCPKeepalive is set to false, if the net.Listener is created by the package itself, it does not override the default behavior of net.ListenConfig, which keeps TCP keepalive enabled. Also added TCPKeepalive and TCPKeepalivePeriod fields to the client to make its behavior consistent with the server. The goal of this update is to ensure that whether TCP keepalive is enabled is entirely controlled by the configuration fields provided by the package when net.TCPConn is created by the package itself.
f0a752c
to
083dd1c
Compare
I'm thinking we should treat this as a backwards incompatible change as it changes the behavior of the library. What do you think about deprecating |
I think that even with the addition of a TCPKeepaliveDisabled field, and maintaining backward compatibility, it is difficult to accurately convey the semantics. I believe that the program's runtime behavior should strictly adhere to the configuration field API. But TCP keepalive seems unlikely to affect the correctness of the program and might only have a minor impact on performance, it may be acceptable to address it in the next major release. Let's leave this issue to be resolved in the next major release. Let's keep this pull request open; we may need more input from others. |
Currently, when Server.TCPKeepalive is set to false, if the net.Listener is created by the package itself, it does not override the default behavior of net.ListenConfig, which keeps TCP keepalive enabled.
I also added TCPKeepalive and TCPKeepalivePeriod fields to the client to make its behavior consistent with the server.
The goal of this pull request is to ensure that whether TCP keepalive is enabled is entirely controlled by the configuration fields provided by the package when net.TCPConn is created by the package itself.
If net.TCPConn is created by the user, it means that on the server side, the user provides their own net.Listener, and on the client side, the user provides their own Dial and DialTimeout functions. The TCP keepalive mechanism is managed by the user in this case, When TCPKeepalive field is false.
If the user provides their own net.Listener, even after this pull request is accepted, the implementation of fasthttp means that Server.TCPKeepalive is only meaningful when set to true. If set to false, it does not change the existing TCP keepalive behavior of the net.TCPConn created by the user-provided net.Listener.
fasthttp/server.go
Lines 1956 to 1967 in 43c7b83
To avoid unnecessary and redundant system calls, I think this behavior is acceptable. At the same time add some relevant comments to make the meaning clearer.
The root of the problem is that the net package defaults to having TCP keepalive enabled, while the fasthttp package defaults to having TCP keepalive disabled. Clearly, the behavior of the fasthttp package is more reasonable.
The changes brought by this pull request makes the semantics of the configuration fields related to TCP keepalive clearer and more precise.
This is a preliminary personal thought; discussions are welcome.