5 ms·
I really really hope Go 2 can do something about `context`. Context is the biggest hidden wart of Go. We need the capabilities of context in different packagi
by infogulch 8y ago
I really really hope Go 2 can do something about `context`. Context is the biggest hidden wart of Go. We need the capabilities of context in different packaging.
- Teckla 8y agoHaving to manually pass context through so many functions in code bases is definitely not ideal.
- infogulch 8y agoIt doubles the surface area of every library that deals with anything related to IO, and forces middle libraries that don't and shouldn't care about context to double their surface area just to support connecting their consumers to their upstream providers. "not ideal" is an understatement.
- dolmen 8y agoMy contextio package might be useful. Check example: https://godoc.org/github.com/dolmen-go/contextio#example-package--Copy https://godoc.org/github.com/dolmen-go/contextio#example-pac...
- atombender 8y agoThis doesn't seem to be a popular opinion, but I agree. It's such a pervasive functionality in concurrent programs that it really should be a built-in aspect of a goroutine. The problem with context isn't necessarily the interface, it is that it is "viral". If you need context somewhere along a call chain, it infects more than just the place you need it — you almost always have to add it upwards (so the needed site gets the right context) and downwards (if you want to support cancellation/timeout, which is usually the point of introducing a context). Context's virality also applies to backwards compatibility. There have been discussions of adding context to io.Reader and io.Writer, for example, but there's no elegant way to retrofit them without creating new interfaces that support a context argument. This problem applies to any API; you may not expect your API to require a context today, but it might need one tomorrow, which would require a breaking API change. Given that it's impossible to predict, you might want to pre-emptively add context as an argument to all public APIs, just to be safe. Not good design. Cancellation/timeout is arguably so core to the language that it should be an implicit part of the runtime, just like goroutines are. It would be trivial for the runtime to associate a context with a goroutine, and have functions for getting the "current" context at any given time. (Erlang got this right, by allowing processes to be outright killed, but it's probably too late to redesign Go to allow that.) (I'm ignoring the key/value system that comes with the Context interface, because I think it's less core. It certainly seems less used than the other mechanisms. For example, Kubernetes, one of the largest Go codebases, doesn't use it.)
- deleted 8y ago[deleted]
- nathanaldensr 8y agoForgive me since I've never used Go, but this sounds similar to having to add the async keyword to methods in C# all the way up the stack once you attempt to use an async method, as well as having to pass CancellationTokens down the stack to support cancellation. I've noticed it pollutes code with a lot of ceremony that I wish had been added to the runtime itself. Is this what you're talking about?
- infogulch 8y agoYeah, context is basically a cancellation token with the same downsides and a bunch of unrelated features piled on (because it came from a bunch of people needing to work around limitations getting together and deciding to put all their hacks in one place, but I digress). But from a certain perspective all functions in go are async by default, so we get to dodge that one.
- atombender 8y agoAbsolutely. Contexts are similar to your CancellationToken; a context contains a channel you can listen to, just like CancellationToken's WaitHandle. They're slightly simpler in that I believe CancellationToken supports registering callbacks, which contexts don't. Go doesn't actually have async support in the sense of promises/futures (as seen in C#, JavaScript, Rust, etc.). The entire language is built around the idea that I/O is synchronous, and concurrency is achieved by spawning more goroutines. So if you have two things that you want to run simultaneously, you spawn two goroutines and wait for them. (Internally, the Go runtime uses asynchronous I/O to achieve concurrency.)
- Groxx 8y ago>Go doesn't actually have async support I usually phrase this part of Go as: no async/await, it only has threads. But no thread handles. Everything is potentially parallel under the hood and all coordination requires external constructs like WaitGroups / chans / etc. async/await has major complications like changing call syntax through the whole chain, so I actually prefer it this way. the lack of thread handle objects (e.g. a return value from `go func()`) is strange IMO tho.
- interesthrow2 8y agoNot making Go routines values like Ada Tasks is what led to awkward solutions shouldered by the developer such as "context". Too many time Go developers were told to solve issues in user-land, this is the consequence of that.
- Rapzid 8y agoIt's not the fastest thing in the world, but task-local storage in C# is pretty great. Miss it much in TypeScript.
- infogulch 8y agoBecause I think discussing actual solutions is better that just complaining, this is my current favorite design document to address context: Go Context Scoping [1] by Eyal Posener. It even has a working PoC implementation [2] which is pretty ergonomic and could become even moreso with language integration. I think this concept solves most of the problems we currently face with context. As a consequence of making context available per goroutine it basically becomes an implementation of gouroutine-local storage. But this is more because context.WithValues exists in the first place than because of this proposal. In fact context has effectively become the de-facto GLS anyway, except it makes everyone's code ugly to do it. [1]: https://posener.github.io/context-scoping/ https://posener.github.io/context-scoping/ [2]: https://github.com/posener/context https://github.com/posener/context
- kochthesecond 8y agoComing from languages that lack such a «convention», I quite like Context. Try implementing something similar in java or even node is also a giant pain