Skip to content
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

replace reusePort by failOnExistingPort, simpler state (single bool), no TOCTOU for numThreads=1 #53

Conversation

timotheecour
Copy link
Contributor

@timotheecour timotheecour commented Jul 15, 2021

should be followed by dom96/jester#281 in jester

alternative to #50 and #52 that hits all the targets:

  • jester can forward jester.reusePort as httpbeast.failOnExistingPort = not reusePort
  • sane default (by default, fails with address already in use in all cases: stdlib's httpserver, jester without httpbeast, and jester with httpbeast)
  • avoid redundant state with 2 bools (reusePort + failOnExistingPort) or a tri-state, instead there's a single bool flag
  • avoids the concern raised in reusePort = false now default; honored regardless of numThreads #50 (comment) ("Yes, but you're doing that by ignoring the flag") since I'm now honoring failOnExistingPort inside httpbeast, it's consistent

The only downside is that this is a breaking change from the previous commit for client code that would've used thew new reusePort flag, but it was introduced very recently (10 days ago), and wasn't the commit I had signed up for, refs #47 (comment)

Sorry, I prefer for this stuff to be explicit. So I changed things.

so I've bumped the version to 0.5.0
(an alternative to this 10 day-window breaking change would be possible by adding a different initSettings2 and deprecating initSettings, or simply define initSettings by interpreting the reusePort argument as not failOnExistingPort; but this software is pre-1.0 and it's only a 10-day window so IMO is acceptable)

Copy link
Owner

@dom96 dom96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to worry about breaking changes for an unreleased piece of software, 0.4.0 was never tagged.

Please don't remove the existing reusePort. Just add the new failOnExisting flag. This PR shouldn't require more than 5 lines of changes.

I've added suggestions for exactly what I have in mind.

@@ -1,6 +1,6 @@
# Package

version = "0.4.0"
version = "0.5.0"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
version = "0.5.0"
version = "0.4.0"

Comment on lines +481 to +484
if settings.failOnExistingPort:
close(newSocketAux(settings)) # attempt to bind to a temporary socket
var settings = settings
settings.failOnExistingPort = false
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if settings.failOnExistingPort:
close(newSocketAux(settings)) # attempt to bind to a temporary socket
var settings = settings
settings.failOnExistingPort = false
if settings.failOnExistingPort:
bindOnExistingTest(settings)

Comment on lines +315 to +320
proc newSocketAux(settings: Settings): owned(Socket) =
result = newSocket(settings.domain)
result.setSockOpt(OptReuseAddr, true)
result.setSockOpt(OptReusePort, not settings.failOnExistingPort)
result.bindAddr(settings.port, settings.bindAddr)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
proc newSocketAux(settings: Settings): owned(Socket) =
result = newSocket(settings.domain)
result.setSockOpt(OptReuseAddr, true)
result.setSockOpt(OptReusePort, not settings.failOnExistingPort)
result.bindAddr(settings.port, settings.bindAddr)
proc bindOnExistingTest(settings: Settings) =
let sock = newSocket(settings.domain)
sock.setSockOpt(OptReuseAddr, true)
sock.bindAddr(settings.port, settings.bindAddr)

Comment on lines -322 to -327
let server = newSocket(settings.domain)
server.setSockOpt(OptReuseAddr, true)
if compileOption("threads") and not settings.reusePort:
raise HttpBeastDefect(msg: "--threads:on requires reusePort to be enabled in settings")
server.setSockOpt(OptReusePort, settings.reusePort)
server.bindAddr(settings.port, settings.bindAddr)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert this.

@dom96
Copy link
Owner

dom96 commented Jun 11, 2022

If you're still interested in pursuing this then please rebase and reopen this PR.

@dom96 dom96 closed this Jun 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants