Instead of passing Context explicitly around, we now have a thread-local Context object Context::current() which is an implicit argument to every function.
Most manipulation of this should use the WithContextValue helper, which augments the current Context to add a single KV pair, and restores the old context on destruction.
Advantages are:
- less boilerplate in functions that just propagate contexts
- reading most code doesn't require understanding context at all, and using context as values in fewer places still
- fewer options to pass the "wrong" context when it changes within a scope (e.g. when using Span)
- contexts pass through interfaces we can't modify, such as VFS
- propagating contexts across threads was slightly tricky (e.g. copy vs move, no move-init in lambdas), and is now encapsulated in the threadpool
Disadvantages are all the usual TLS stuff - hidden magic, and potential for higher memory usage on threads that don't use the context. (In practice, it's just one pointer)
Maybe we could return const Context& here and have a separate setCurrent() method for replacing the current context?
Most of the clients shouldn't mutate the contexts anyway, and finding the few that do seems easier if there's a separate method for that.