I agree on the fact that passing a Context everywhere is impossible in some cases - just think about the many APIs (from standard library and 3rd parties) that do not accept a Context - and in some other cases very complicated, requiring extensive refactoring.
I also agree with the recommendation to *DO* pass a Context when feasible. It's just that sometimes it's not feasible, and infact in my case (a Go interpreter) I was forced to resort to goroutine-local storage as the only possible solution. If you are interested, you can have a look at my fast (one line of assembly) implementation: https://github.com/cosmos72/gls On Tuesday, October 30, 2018 at 5:34:06 AM UTC+1, robert engels wrote: > > I agree. I’ve read the arguments against thread-local (or goroutine local > storage), and the passing of Context everywhere instead. It doesn’t make > sense to me. > > Even a simple runtime.GetGoID() that returned a unique int would allow the > design of much simpler server software. > > But I don’t think it is going to change, so get to know ‘refactor method > signature in IntelliJ’ really well. > > On Oct 29, 2018, at 10:28 PM, Tang Shiwei <siweit...@gmail.com > <javascript:>> wrote: > > > > Now i have the same problem as you, i need to record log id through a web > request, and pass the log id by httpContext, its look orderless for my > code, so sad! > > > On Thursday, February 25, 2016 at 1:59:11 AM UTC+8, Damian Turczyński > wrote: >> >> Kevin >> >> I have in my opinion valid reason. I'm writing a web server in go. I want >> to have logs across all application to include requestID. The only way I >> can do that is to pass httpContext everywhere! Which is hilarious, and >> super unclean. In other languages/frameworks it is possible as you have >> something like HttpContext accessible globally, and yet of course you have >> to deal with spawning child threads with care and maybe even to pass >> httpContext there but it's much smaller hustle than passing httpContext in >> every single function I'll write in my application. >> >> On Sunday, October 14, 2012 at 1:36:25 PM UTC+1, Kevin Gillette wrote: >>> >>> That should be fine, but in this case, it'd be better to refer to it as >>> 'task specific' instead of 'goroutine local', since your struct >>> isn't/shouldn't be designed around the assumption that it's goroutine local. >>> >>> The big issue with stuff not being freed is when a map of goroutine id >>> to data is used (if the goroutine exits without deleting its data from the >>> map, a leak has occurred), not to mention that there are _extremely_ few, >>> if any (I'm strongly edging towards there being none) legitimate reasons to >>> store data based on goroutine Id -- that kind of thinking is generally a >>> carryover for languages that are much less effective at handling >>> concurrency. >>> >>> On Saturday, October 13, 2012 9:12:40 AM UTC-6, bryanturley wrote: >>>> >>>> >>>> On Sat, Oct 13, 2012 at 8:54 AM, bryanturley <bryan...@gmail.com> >>>>> wrote: >>>>> >>>>>> What I do when i need something like this is >>>>>> >>>>>> type LilSrv struct { >>>>>> // bleh >>>>>> // your goroutine local stuff here nicely predefined >>>>>> // some chans to talk to it >>>>>> } >>>>>> >>>>>> func (ls *LilSrv) MLoop() { >>>>>> for { >>>>>> // bleh, stuff >>>>>> } >>>>>> } >>>>>> >>>>>> ... somewhere in your code >>>>>> >>>>>> ls = new(LilSrv) // or similar >>>>>> go ls.MLoop() // normally i have this wrapped in something like >>>>>> "NewLilSrv() (ls *LilSrv)" >>>>>> >>>>>> now that ls is your goroutine local storage without using c code or >>>>>> any other way to low level for normal use code. >>>>>> >>>>>> >>>> Are you saying the ls in my example won't get GC'ed when it isn't in >>>> use anymore? >>>> What I exampled here is done throughout the standard library... for >>>> instance inside >>>> http://golang.org/src/pkg/net/http/server.go?s=30567:30613#L1015 >>>> c, e := newConn() few lines later >>>> go c.serve() >>>> I think my phrasing just confused you. >>>> The entire idea of this was to make it not a global state, just a >>>> struct that got allocated before the goroutine started that was explicit >>>> to >>>> that goroutine and others that need to talk to it. >>>> And if a new goroutine is started in ls.MLoop it doesn't necessarily >>>> even matter if it can see that ls. >>>> >>>> The real problem was a single global name that lived in a new spot >>>> automagically each thread, that is clearly not happening here. >>>> >>>> > On Thursday, February 25, 2016 at 1:59:11 AM UTC+8, Damian Turczyński > wrote: >> >> Kevin >> >> I have in my opinion valid reason. I'm writing a web server in go. I want >> to have logs across all application to include requestID. The only way I >> can do that is to pass httpContext everywhere! Which is hilarious, and >> super unclean. In other languages/frameworks it is possible as you have >> something like HttpContext accessible globally, and yet of course you have >> to deal with spawning child threads with care and maybe even to pass >> httpContext there but it's much smaller hustle than passing httpContext in >> every single function I'll write in my application. >> >> On Sunday, October 14, 2012 at 1:36:25 PM UTC+1, Kevin Gillette wrote: >>> >>> That should be fine, but in this case, it'd be better to refer to it as >>> 'task specific' instead of 'goroutine local', since your struct >>> isn't/shouldn't be designed around the assumption that it's goroutine local. >>> >>> The big issue with stuff not being freed is when a map of goroutine id >>> to data is used (if the goroutine exits without deleting its data from the >>> map, a leak has occurred), not to mention that there are _extremely_ few, >>> if any (I'm strongly edging towards there being none) legitimate reasons to >>> store data based on goroutine Id -- that kind of thinking is generally a >>> carryover for languages that are much less effective at handling >>> concurrency. >>> >>> On Saturday, October 13, 2012 9:12:40 AM UTC-6, bryanturley wrote: >>>> >>>> >>>> On Sat, Oct 13, 2012 at 8:54 AM, bryanturley <bryan...@gmail.com> >>>>> wrote: >>>>> >>>>>> What I do when i need something like this is >>>>>> >>>>>> type LilSrv struct { >>>>>> // bleh >>>>>> // your goroutine local stuff here nicely predefined >>>>>> // some chans to talk to it >>>>>> } >>>>>> >>>>>> func (ls *LilSrv) MLoop() { >>>>>> for { >>>>>> // bleh, stuff >>>>>> } >>>>>> } >>>>>> >>>>>> ... somewhere in your code >>>>>> >>>>>> ls = new(LilSrv) // or similar >>>>>> go ls.MLoop() // normally i have this wrapped in something like >>>>>> "NewLilSrv() (ls *LilSrv)" >>>>>> >>>>>> now that ls is your goroutine local storage without using c code or >>>>>> any other way to low level for normal use code. >>>>>> >>>>>> >>>> Are you saying the ls in my example won't get GC'ed when it isn't in >>>> use anymore? >>>> What I exampled here is done throughout the standard library... for >>>> instance inside >>>> http://golang.org/src/pkg/net/http/server.go?s=30567:30613#L1015 >>>> c, e := newConn() few lines later >>>> go c.serve() >>>> I think my phrasing just confused you. >>>> The entire idea of this was to make it not a global state, just a >>>> struct that got allocated before the goroutine started that was explicit >>>> to >>>> that goroutine and others that need to talk to it. >>>> And if a new goroutine is started in ls.MLoop it doesn't necessarily >>>> even matter if it can see that ls. >>>> >>>> The real problem was a single global name that lived in a new spot >>>> automagically each thread, that is clearly not happening here. >>>> >>>> > -- > 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...@googlegroups.com <javascript:>. > 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.