-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: context: Add unique context ID accessible via context.Context.Value() #69805
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
Comments
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
It seems to me that |
@andriiyaremenko What exactly are you trying to do? Why do you need a map at all, instead of just using |
I'm sorry, it's my first proposal and I'm clearly bad describing problems.
I'm trying to describe a situation when I'm trying to always return the same service for the same context, for example in dependency injection library. The only reason I created this proposal was my thought that I can't be the only one who wished there was a better way to identify the context and distinguish two contexts in better and faster way than storing and comparing them. If I'm wrong, I'll close this issue and try to use what Go already has. |
This feels like misusing contexts as an identifier, you should probably have some other identifier that you can more reliably create and use, especially since this ID is not like how most context values work within a tree of contexts |
That's precisely the reason this proposal was created. I want reliably distinguish between contexts and tell when I received the same context. I suggested adding it as an ID that can be obtained from |
We can't change the It occurs to me that |
That's also the reason why I didn't want to suggest changing the interface. I imagine something like: type withID struct {
id uint64
parent Context
}
func (w *withID) Deadline() (deadline time.Time, ok bool) {
return w.parent.Deadline()
}
func (w *withID) Done() <-chan struct{} {
return w.parent.Done()
}
func (w *withID) Err() error {
return w.parent.Err()
}
func (w *withID) Value(key any) any {
switch {
case key == ContextIDKey && w.Err() == nil:
return w.id
case key == ContextIDKey:
return uint64(0)
default:
return w.parent.Value(key)
}
}
func WithID(ctx Context) Context {
withID := &withID{parent: ctx}
withID.id = uint64(reflect.ValueOf(withID).Pointer())
return withID
} but add part with setting |
I'm not convinced that this is a widely used pattern that needs native support. Note that |
Makes sense. I'm closing the issue. |
Proposal Details
What:
I propose to add
context.ContextIDKey
(or any other better name), that will be used as (example):It should return unique ID (not string, int64 maybe?) for every context instance and be accessible for any context instance created via go standart library.
Why:
Sometimes, not often, I find myself struggling to find a good way to associate objects with
context.Context
passed into the function, when I do not want to add them to the context via.WithValue()
or have no option to use it.For example: I have a
map[context.Contex]SomeService
, where I lookup values based on context passed into the function as argument.It is possible and would work, but it takes considerably more time compared to working with
map[int]SomeService
.When I'm saying considerably more time consider this benchmark:
Here are the results:
And this difference can accumulate when working with a lot of instances of context simultaneously.
I'm not sure it will be widely used, but it will for sure help in some cases like described above.
If it is a duplicate - I'm sorry. I tried to find if anyone had already proposed it, but found no issue dedicated to it.
The text was updated successfully, but these errors were encountered: