-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: spec: make context.Context a predefined type like error #20282
Comments
If Context does become more official, it's worth also considering whether it should be more magic. We don't want to do goroutine-local storage, but you could imagine some sort of scheme whereby contexts arguments are always present or at least declared but passed implicitly by default, unless explicitly passed separately. Everything I think of is pretty gross, but there might be something there. |
I should note that more magic handling around errors have been proposed many times in the past as well. Magic handling of context should be considered along with more magic handling of errors. |
One simple idea would be to have something like context.This() return the "implicit context" for the current goroutine, and then everything would work like now but without having to explicitly thread a context through all function calls and all libraries. I would love something even more integrated (as you say, if you propagate errors, you can also propagate context errors and at that point it gets even more magic) but this would be a start. |
I am very strongly opposed to removing error from the universe block, I
remember os.Error and I don't want to go back to that.
…On Tue, 9 May 2017, 05:41 Giovanni Bajo ***@***.***> wrote:
One simple idea would be to have something like context.This() return the
"implicit context" for the current goroutine, and then everything would
work like now but without having to explicitly thread a context through all
function calls and all libraries.
I would love something even more integrated (as you say, if you propagate
errors, you can also propagate context errors and at that point it gets
even more magic) but this would be a start.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#20282 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAAcA4OGmcqCDh-4BZ-APNmpBHcTd2spks5r32_SgaJpZM4NURSd>
.
|
I personally feel that error is really a very special case of interface in go. In no other case I really need to return a nil interface, it is the only interface that where a nil interface value has a meaning. So comparison with error is generally not a close comparison. ps: it turns out they are indeed related: |
If context.Context became a builtin and remained a interface, maybe it's worth considering changing the interface to be: Deadline() (time.Time, bool)
Done() <-chan struct{}
Err() error
Parent() context.Context Now you have opened up a opportunity for user space implementations of not just Context values, but actual context. Part of the reason no specialized context libraries have emerged is due to the fact the context package is tightly coupled to itself to find parent and call cancellation functions (parentCancelCtx). So one can not implement a user context from top down that plays well at all with the std lib or optimizes away any inefficiencies. You can't make a map to use for context.Value for example to store just your app state to prevent the 6-8 allocs that come with stdlib context.WithValue because if a context is injected between yours you can't reliably traverse up to your object. With a Parent method you could, and all existing instances of (context.Context).Value(...) simply get changed to context.Value(...) a top level function call implemented using context.Parent() to walk up the tree until it asserts it's own private valuecontext type. Tooling could do this task very easily.. and then we can finally implement our own context and perhaps a set of context packages outside of std library can emerge for special purpose cases. If such a change is off the table at least we could consider a refactor of stdlib to define a optional interface in that package which would allow an efficient implementation of cancellation without having to fire new goroutines and the allocations along with it. // Canceler is the interface that wraps the basic Cancel method.
//
// If a context implements Cancel then it is expected that once a call to Cancel
// completes the context is done.
type Canceler interface { Cancel() } The only issue with this is it possible outside of a per-package basis for child contexts to signal cancellation to parents via a library feature, such as ctxcancel.Cancel(context.Context), which certainly goes against the spirit of context. |
This seems less-worse than |
If we ignore context values why not reduce it all the way down to just the cancel channel stored internally per gouroutine and let cancel := go func() {
<- runtime.Done() // fetches this goroutines cancel channel
}()
cancel() timeout: cancel := go func() {
<- runtime.Done()
}()
time.AfterFunc(10 * time.Millisecond, cancel) Advantages:
Drawbacks:
|
Context is not just for cancellation, it can also contain security or tracing or deadline information for a call. My understanding is that the decision to make context explicit in go in place of implicit as in say C++ was an intentional thoroughly discussed one. |
Riffing off of #20282 (comment) , here's an incomplete and not fully thought out, but reasonably concrete proposal for the value-storing aspects of context, with plenty of room for bikeshedding. (No mention of cancellation here, those can be two separate problems/mechanisms.)
In this idea, context is implicit, scoped separately from functions or goroutines so you can call multiple helpers with slightly different contexts, and stored likely in the callstack with parent pointers across goroutines. And yes, as-is it adds keywords; I considered that cleaner than |
One of the reasons to make
Any magical handling of Closing. |
Split from #20280, @rasky @zombiezen
Should
context.Context
be part of the language? Currently,error
is an interface type defined in the language and is a pervasive type that is commonly returned from functions. Thecontext.Context
type can be seen as sort of the reverse oferror
, where it is a pervasive type that is commonly passed to functions.However, one challenge with the
context.Context
interface is that theContext.Deadline
method returns atime.Time
, which probably should not be promoted to the language itself.Personally, I can see the opposite being more likely: that
error
be pulled out of the language specification and instead be defined in theerrors
package. (In fact, it used to be a library defined type asos.Error
).It would be consistent if
context.Context
anderror
were given equal treatment from the perspective of the language in Go2.Go ahead and discuss.
The text was updated successfully, but these errors were encountered: