In the Go FAQ it's clearly stated that having Goroutines do not have IDs due to various reasons. Nevertheless the x/net/http2 library makes use of Goroutine IDs in https://github.com/golang/net/blob/master/http2/gotrack.go#L51.
Having x/net/http2 use Goroutine IDs seems to be proving the case for having Goroutine IDs at least for debugging purposes, doesn't it?
the case for having Goroutine IDs at least for debugging purposes, doesn't it?
If you make this easy/officially supported, how do you prevent people from using it for non-debugging purposes?
the case for having Goroutine IDs at least for debugging purposes, doesn't it?
If you make this easy/officially supported, how do you prevent people from using it for non-debugging purposes?
It could be enabled by a runtime flag. Does it even have to be restricted to debugging purposes?
My main concern here is that the FAQ makes a pretty strong case against having such IDs in the first place. So probably the better way here is to change x/net/http2 to not use Goroutine IDs. As the FAQ states:
For those cases where a particular goroutine is truly special, the language provides features such as channels that can be used in flexible ways to interact with it.
My main concern here is that the FAQ makes a pretty strong case against having such IDs in the first place.
Not really. The FAQs just explains why goroutines IDs are not readily exposed to the programmer:
They expose no unique identifier, name, or data structure to the programmer.
The bottom reason is: to discourage certain usage patterns that the Go designers deemed unappealing; and to, on the other hand, encourage safer and simpler concurrency design patterns.
That doesn't mean that every single attempt to ID goroutines is misguided and undesirable. It's similar to the ternary operator situation: it's not in Go because the Go designers wanted to encourage programmers to use plain ifs and to avoid writing unreadable inline-conditions code. Nobody is saying that every single possible way to use the ternary operator would result in unreadable code. It can be used correctly. But it is often abused, so it was left out of the language.
So probably the better way here is to change x/net/http2 to not use Goroutine IDs
I'm not saying we should not, but... why? Is that specific piece of code causing anyone any issue? If yes, then please explain what the issue is.
Thanks for following up, @ALTree! IMHO it's a bad role model to not expose Goroutine IDs on the one hand but on the other hand make use of them in the (to be) stdlib. To pick up your example: The ternary operator doesn't exist at all in Go so there's really no way to use it (even when you know what you're doing). This is different with Goroutine IDs because they do exist but just are not exposed even though there are valid use cases for them as the x/net/http2 example clearly shows.
I don't quite see what the problem is here. x/net/http2 only uses goroutine IDs for debugging purposes. It uses a slow mechanism for computing the goroutine ID, one that would likely not be suitable for production code. Other code can make the same choice. The code is right there.
If we add an efficient mechanism for obtaining a goroutine ID, people will inevitably use it for production, not just for debugging. And that will lead to a style of Go programming that I, at least, think would be inadvisable.
What is stopping you from using the code in x/net/http2?
My proposal is to extend https://golang.org/doc/faq#no_goroutine_id to name one or more edge cases and real-world examples where the usage of Goroutine IDs is valid, e.g. in x/net/http2. This would be truly transparent IMHO and lets people look at when (and only when) it's really useful to have the ID at hand.
@ianlancetaylor
If we add an efficient mechanism for obtaining a goroutine ID, people will inevitably use it for production, not just for debugging.
On the one hand, it is already possible to hand-patch the Go runtime to add such a mechanism — so motivated folks who have control of their full stack and want goroutine IDs in production can do that anyway.
It seems to me that the main effect of lacking such a mechanism today is that _library authors_ cannot make use of it, since they can't assume that their users are carrying local patches.
But even they could already customize the code for local patches based on build tags — that's only a marginally higher impediment than, say, a runtime/debug hook that must be explicitly enabled using an option in the GODEBUG environment variable.
@makkes I think the FAQ should stay simple. I don't think it's helpful to point to dreadful code like that in x/net/http2.
@bcmills We can only define what the standard library does. In any case I don't think we want to encourage an ecosystem of standard library extensions attached to well known build tags. That sounds complex.
@ianlancetaylor, I'm not suggesting that we define our own build tag for goroutine IDs. I'm suggesting that we could define a function (in runtime/debug) that is always present (so no build tags required) but requires an explicit GODEBUG setting to activate (so that library authors can't make assumptions about goroutine IDs being available at run time).
That would also make the position on goroutine IDs clearer: that they are a tool for debugging only, no more and no less.
@bcmills Ah, sorry, I misunderstood.
@makkes I think the FAQ should stay simple. I don't think it's helpful to point to dreadful code like that in x/net/http2.
As far as I understood x/net/http2 it's supposed to eventually end up in the stdlib. Do you think it's a good idea to have so-called "dreadful code" in the stdlib? People actually look at that for learning and best practices.
The top priority of the standard library is to provide functionality needed by Go programs. Serving as an example of Go best practices is important but is a lower priority.
Fair enough. Thanks for all the clarifying comments!
Most helpful comment
@ianlancetaylor, I'm not suggesting that we define our own build tag for goroutine IDs. I'm suggesting that we could define a function (in
runtime/debug) that is always present (so no build tags required) but requires an explicitGODEBUGsetting to activate (so that library authors can't make assumptions about goroutine IDs being available at run time).That would also make the position on goroutine IDs clearer: that they are a tool for debugging only, no more and no less.