-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Fix: configurable SO_REUSEPORT socket setting (disabled by default) #4046
Fix: configurable SO_REUSEPORT socket setting (disabled by default) #4046
Conversation
I also chose to not allow to configure |
self.reuse_port = true | ||
rescue Errno | ||
end | ||
self.reuse_port = true if reuse_port |
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.
Bonus: now we can raise if the OS doesn't support SO_REUSEPORT
, since it's now explicitly enabled.
src/http/server.cr
Outdated
@@ -138,8 +138,8 @@ class HTTP::Server | |||
end | |||
end | |||
|
|||
def bind | |||
@server ||= TCPServer.new(@host, @port) | |||
def bind(reuse_port = false) |
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.
Wouldn't it make more sense to have either all of host, port and reuse_port on #bind
, or all in either .new
or #listen
. I appreciate it makes the API a bit more unwieldy but it seems to me that reuse_port
option should be in the same place as port
and host
.
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.
Maybe. I have no strong opinion here.
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.
In the discussion of this issue we suggested to make it a property of HTTP::Server
. What's wrong with that? That way it's used in both bind
and listen
, and if you stop the server and start it again the configuration is preserved.
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.
A few things:
host
andport
aren't properties, why shouldreuse_port
be?reuse_port
, ashost
andport
, only applies before binding the socket;- stopping and restarting HTTP::Server... will that happen? I'm not sure this is even possible (as of now).
Maybe an argument to #new
would be better, just like TCPServer#new
.
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.
But we have like 8 constructors, it will clutter the API.
For me, having it as a property or as named arguments in bind
/listen
works well too. But I'd probably add it to both listen
and bind
, because it's not very common to do bind
+ listen
, just listen
.
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.
Allright. Do we need the property is we add the argument to both listen
and bind
? Just say "yes" or "no" :-)
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.
no :-)
099f387
to
8c2e073
Compare
This led to confusing behavior when starting different TCP services that default to the same default ports. They didn't fail to start, but were failing to receive some requests. The setting is now configurable and disabled by default. You may enable it by setting the `reuse_port` named argument to true in the following methods: TCPServer.new TCPServer.open HTTP::Server#bind HTTP::Server#listen
8c2e073
to
a2b3209
Compare
Updated so |
This led to confusing behavior when starting different TCP services that default to the same default ports. They didn't fail to start, but were failing to receive some requests.
I propose here to allow the setting to be easily configured and to disable it by default. You may enable it by setting the
reuse_port
named argument to true. For example:MaybeBoth#listen
could accept thereuse_port
but I think#bind
is a better place. Same for#new
which would require to memoize the choice until we call#bind
. I favored explicitness.HTTP::Server#bind
andHTTP::Server#listen
now accept thereuse_port
method.fixes #4019