24 lines
1.8 KiB
Markdown
24 lines
1.8 KiB
Markdown
![]()
4 months ago
|
# Using Context
|
||
|
|
||
|
Remember that a common pattern of signaling events or completion is using a blocking channel that receives and empty struct. An empty struct has zero memory footprint. It is typically used to signal completion or stopping.
|
||
|
|
||
|
The Context.Done() returns a channel that is closed when this Context is canceled `Done() <-chan struct{}`. Contexts have a root and can form a parent child tree structure. A child is "derived" from a parent context and when a Context is cancelled all derived contexts are also canceled. WithCancel and WithTimeout return derived Context values that can be canceled sooner than the parent Context.
|
||
|
|
||
|
> Incoming requests to a server should create a Context, and outgoing calls to servers should accept a Context. The chain of function calls between them must propagate the Context, optionally replacing it with a derived Context created using WithCancel, WithDeadline, WithTimeout, or WithValue. When a Context is canceled, all Contexts derived from it are also canceled.
|
||
|
|
||
|
## What about Context.Value
|
||
|
|
||
|
The problem with context.Values is that it's just an untyped map so you have no type-safety and you have to handle it not actually containing your value. You have to create a coupling of map keys from one module to another and if someone changes something things start breaking.
|
||
|
|
||
|
In short, if a function needs some values, put them as typed parameters rather than trying to fetch them from
|
||
|
context.Value
|
||
|
. This makes it statically checked and documented for everyone to see.
|
||
|
|
||
|
Context.Value is good for things like "A trace ID". It's information that is not needed for by every function in the call stack.
|
||
|
|
||
|
> Context.Value should inform not control. The content of context.Value is for maintainers not users. It should never be required input for documented or expected results.
|
||
|
|
||
|
## Readings
|
||
|
|
||
|
https://go.dev/blog/context
|
||
|
https://go.dev/blog/pipelines
|