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
x/website/_content/doc: Channels example in Effective Go leaks goroutines #33804
Comments
CC @robpike |
I dont understand how the original example leaks goroutines. The handler goroutines (which are long-living and bounded) will go away when the request channel is closed. |
I realize that, but this is the mechanism that leads to goroutine leaks. It's a subtle point not mentioned in Effective Go or in Tour and, as of now, the docs actually guide users towards buggy usage of channels. Leaked goroutines are one of the most common, if not the most common, concurrency-related bugs in Go programs. If you put yourself in the shoes of a programmer new to Go, the current snippet strongly suggests that the way to exit I thought about suggesting we put a doc comment in the snippet explaining that the As it stands, this snippet is suggesting it's perfectly fine for an exported function to hold goroutines open indefinitely, even after signaling it to exit through a channel...I can't imagine a good argument for recommending that practice. |
See #28782. I have resisted changes like this in the past not because your reasoning is wrong, but because the whole document needs to be replaced. If we do anything for your issue, it should be no more than a clarifying sentence. |
That’s fair—I think a single sentence is sufficient, something like: “In the snippet below, the handler goroutines will remain in memory and blocked on clientRequests (even after Serve exits) until the channel is closed.” |
Closing a channel tells consumers that the producer has no further data to send, but buffered data may still be marinating in that channel. As such, the consumer won't be made-aware of the close until the entire buffet is eaten. The quit channel is an interrupt that should take priority over the already-buffered items. It would make more sense for the handlers to know about the quit channel than have complex re-serialization logic that merely stops sending items to the handlers. |
@as sure—as I said, I tried to pick a solution that didn't rearrange the program too dramatically. There was a choice between transferring elements from |
The final example in Effective Go's Channels section leaks goroutines. Here's a solution that preserves the original semantics of
Serve
, and is closest to a similar example presented in Tour:The text was updated successfully, but these errors were encountered: