On 14 August 2017 at 07:08, 'Axel Wagner' via golang-nuts <golang-nuts@googlegroups.com> wrote: > For the general interest: I wrote up my thoughts on this in a lengthy blog > post: > Why context.Value matters and how to improve it > In particular, I sketch a design how context.Value could be made a > language-level feature removing most of the disadvantages often ascribed to > it. With this I am trying to put a more concrete face to the ideas behind > the suggestion of using goroutine-local storage or the like to solve the > issues. While I can't speak for others, I see similar ideas hinted at in > this thread. > > I hope this can help to steer the discussion into the more helpful > underlying questions, instead of getting hung up on details of the current > implementation.
Thanks for the blog post. ISTM that you're essentially proposing package-scoped thread-local variables. I don't think that's is a good fit for Go. Specifically, it doesn't work when channels are used to transfer control flow - for example by passing a function through a channel to an existing goroutine that calls the function. There are also possible issues the when a goroutine is started in the context of a request, but actually is nothing to do with that request. For example a long-scoped object might lazily create a service goroutine the first time that it's used - with this proposal, its dynamic scope would retain the context of the first request that happened to trigger its creation. The context.Context type might be a little unwieldy, but I believe that its explicitness is a good thing. > > On Sat, Aug 12, 2017 at 12:59 AM, Sam Vilain <s...@vilain.net> wrote: >> >> On Monday, 7 August 2017 09:06:23 UTC-7, Daniel Theophanes wrote: >>> >>> In the projects I've worked on the switch to Context has been a huge win >>> all across the board. I think it would be sweet to find an effect way to >>> make io.Reader take a context (I often want just that, and when I really >>> need it the solution tends to be more inefficient then it could be). >> >> >> Right; the blocking-style interface of io.Reader is a problem here; I >> didn't really consider this, but my proposal (on its own thread) solves this >> problem; readers that know how can read from the sync.Done channel (which >> would have to be a 'close on cancel' type channel to allow multiple >> readers). >> >>> >>> As for Context.Values, I think you are dismissive of the real use-cases >>> without giving proper weight to them. It can be abused. Just like >>> go-routines and channels. I'm not saying we can't do better then the current >>> implementation, we probably can if the benefit is seen as worth the cost of >>> the change. >> >> >> +1. I used the values interface first and found it much better than >> adding extra parameters to every function, or passing around large interface >> types with a bunch of getter methods. >> >>> You're saying context is viral. It is. Just like errors are viral. Once >>> you start returning them you need to propagate them back. Having a context >>> argument is saying "this function, or something this function calls may >>> block for undisclosed amounts of time and we need to know when to stop >>> blocking and back out." >> >> >> Or "this function wants to log or profile some inner function" or "this >> function wants to use cached objects read within the same transaction". >> >> In my experience, in real server applications you always want these >> abilities, but few structure their code to include context arguments. The >> status quo is that logging is almost always really bad in Go server >> applications. Caching values read within a transaction is too hard so >> you'll make more DB calls than necessary. Profiling never covers the >> tightest loops in your code. This should be easy to add to an existing >> application without massive refactoring. >> >>> >>> There might be a better way to do ctx (and maybe errors) if the language >>> was adjusted; I'm fairly sure go-routine local storage isn't the answer but >>> maybe something else would be. Maybe you could create an Arena with a >>> context and a pattern for returning execution on error and an Arena could >>> use multiple go-routines and such. However I think where you would need to >>> start is a named real experience building and maintaining a solution in Go >>> that gets real use. Then look at it and see where it was painful and how it >>> was so. >> >> >> "Goroutine Local Storage" is bad in my opinion because it's effectively a >> global, even if it is private to the goroutine. I believe context.Context >> is the right pattern, in that values are rolled back as the call stack >> unwinds, and building it inside the runtime allows performance optimizations >> (variable elimination, slot unrolling, combination of context values into >> per-scope arenas) which would otherwise be impractical or ugly. >> >> Sam >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. > > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.