-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
Go version
1.23.0
Output of go env
in your module/workspace:
N/A
What did you do?
The documentation for context.Context#WithValue (as seen here) is misleading. It specifies "WithValue returns a copy of parent in which the value associated with key is val."
What did you see happen?
In practice, "WithValue" doesn't return a copy of the parent, but rather returns a Context instance pointing to the original parent directly. This isn't mentioned explicitly, in contrast to "WithCancel"/"WithTimeout" where it is written in the intro section.
This means that repeatedly calling WithValue
on a Context instance can lead to a memory leak even if it's the same single key that is being overriden (in fact, that is a real problem I experienced). Example snippet demonstration the problem:
func doWork(ctx context.Context) {
for {
uuid := getSomeID()
ctx = ctx.WithValue("id", uuid)
...
}
}
I'm not sure if there is a reason to truly create a child context instead of a copy as described in the documentation, but either way probably either the documentation or the behavior should be changed.
What did you expect to see?
Either the documentation clearly mentioning that WithValue also creates a child context (like it mentions for WithCancel), or changing the behavior so it will use a copy of the original context instead of directly pointing to it.