That is actually a great point I haven't thought about and the crux of the matter (sorry for repeating it, but I think it's worth making very explicit):
While cancelFunc can only be called from the goroutine that created the context, Err can be called downstack. Meaning, if I call cancelFunc, a call *might or might not* return Cancelled as an error. It might not actually implement cancellation or the call might have failed or succeeded concurrently with a different (non-)error. The ctx.Err() return thus allows a "child-function" to signal back whether a cancellation was *successful*; the creator of the context only know that it has been *tried*. On Thu, Nov 3, 2016 at 12:19 AM, Gustavo Niemeyer <gust...@niemeyer.net> wrote: > > > On Wed, Nov 2, 2016 at 9:11 PM, Ian Davis <m...@iandavis.com> wrote: > >> On Wed, Nov 2, 2016, at 10:35 PM, Gustavo Niemeyer wrote: >> >> Hello there, >> >> On Wed, Nov 2, 2016 at 11:09 AM, Ian Davis <m...@iandavis.com> wrote: >> >> >> >> On Wed, Nov 2, 2016, at 12:56 PM, 'Axel Wagner' via golang-nuts wrote: >> >> AIUI: A child or grandchild function is not supposed to signal that. They >> can return an error and let the parent cancel, or they can create their own >> child context WithCancel and cancel that. Context doesn't replace >> exceptions. >> >> >> >> OK I see that. I think I don't understand the purpose of the Err method >> if the function that creates the context is the one that cancels it or >> closes the Done channel. It seems that the only purpose would be to detect >> a Timeout. >> >> >> Err allows you to do this: >> >> select { >> case <-ctx.Done(): >> return ctx.Err() >> ... >> } >> >> >> In this situation, other than a timeout, what would be closing the Done >> channel? The goroutine that created the context already knows the error >> since it's the only one that is supposed to call cancel. >> > > The goroutine that created the context closes the channel. The error > returned informs the call site why the task was interrupted, and that call > site will often not be the calling goroutine. Without it you'd have to > return fmt.Errorf("interrupted") or something, which is both more boring > and less precise than simply calling ctx.Err(). > > > >> You should consider context a way to implement dynamic scoping >> <https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scoping>. >> A context is a thing valid for the current stack frame and downwards and >> should never affect the stack upwards. Which is also why there's the "put >> values in there, not pointers" rule; if you have a pointer, it might modify >> an upstack context. >> >> The advantage of that (and context in general) is, that you don't need to >> worry too much about synchronization and everything; as a context is >> fundamentally immutable (-ish), it's fine to pass it to separate >> goroutines, because they can only do stuff with it downstack. >> >> >> Yes, this is what I am trying to do. I was wondering whether the returned >> cancelFunc is something that could be passed downstream to signal parents >> that work should be aborted. >> >> >> No, the purpose of Context is the opposite: fired tasks are free to do >> whatever they please until it's time to stop, because the boss says so. >> Once that happens, error propagation happens as usual to tell what went >> wrong. >> >> The http://gopkg.in/tomb.v2 package works closer to the model you >> describe. >> >> >> Thanks. I've used tomb before and I've played with the context/tomb >> integration. I guess I need both. >> > > Yeah, tomb and context have some overlap, but they cover different needs. > Pretty much every use I made of tomb was on an internal implementation > detail to organize the required concurrency inside a service, while context > is very nice across API boundaries. > > > gustavo @ http://niemeyer.net > > -- > 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.