-
Notifications
You must be signed in to change notification settings - Fork 137
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
remotedb/grpcdb: fix net.Listener leak in ListenAndServe #269
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,17 @@ import ( | |
// ListenAndServe is a blocking function that sets up a gRPC based | ||
// server at the address supplied, with the gRPC options passed in. | ||
// Normally in usage, invoke it in a goroutine like you would for http.ListenAndServe. | ||
func ListenAndServe(addr, cert, key string, opts ...grpc.ServerOption) error { | ||
func ListenAndServe(addr, cert, key string, opts ...grpc.ServerOption) (rerr error) { | ||
ln, err := net.Listen("tcp", addr) | ||
if err != nil { | ||
return err | ||
} | ||
defer func() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there some reason we shouldn't simply defer the close unconditionally? This function blocks until the server terminates anyway, and we're not checking the result of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The listener is created in this scope, it cannot be closed anywhere else. |
||
if rerr != nil { | ||
_ = ln.Close() | ||
} | ||
}() | ||
|
||
srv, err := NewServer(cert, key, opts...) | ||
if err != nil { | ||
return err | ||
|
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.
can you explain how rerr is ever mutated so that line 25 could ever be true?
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.
Go has a feature called "named results" https://go.dev/ref/spec#Function_types whereby if you name a return value, in a defer you can check against that value so what the last return set will now be captured by that return.
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
return
at the end sets it. (Normal returns also set named return values)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.
@tychoish