Copyright | (c) Ian Duncan 2021 |
---|---|
License | BSD-3 |
Maintainer | Ian Duncan |
Stability | experimental |
Portability | non-portable (GHC extensions) |
Safe Haskell | None |
Language | Haskell2010 |
Thread-local contexts may be attached as implicit state at a per-Haskell-thread level.
This module uses a fair amount of GHC internals to enable performing lookups of context for any threads that are alive. Caution should be taken for consumers of this module to not retain ThreadId references indefinitely, as that could delay cleanup of thread-local state.
Thread-local contexts have the following semantics:
- A value
attach
ed to aThreadId
will remain alive at least as long as theThreadId
. - A value may be detached from a
ThreadId
viadetach
by the library consumer without detriment. - No guarantees are made about when a value will be garbage-collected
once all references to
ThreadId
have been dropped. However, this simply means in practice that any unused contexts will cleaned up upon the next garbage collection and may not be actively freed when the program exits.
Note that this implementation of context sharing is mildly expensive for the garbage collector, hard to reason about without deep knowledge of the code you are instrumenting, and has limited guarantees of behavior across GHC versions due to internals usage.
Why use this implementation, then? Depending on the structure of libraries
that you are attempting to instrument, this may be the only way to smuggle
a Context
in without significant breaking changes to the existing library
interface.
The rule of thumb: - Where possible, use OpenTelemetry.Context in a reader-esque monad, or pass it around directly. - When all else fails, use this instead.
Synopsis
- getContext :: MonadIO m => m Context
- lookupContext :: MonadIO m => m (Maybe Context)
- attachContext :: MonadIO m => Context -> m (Maybe Context)
- detachContext :: MonadIO m => m (Maybe Context)
- adjustContext :: MonadIO m => (Context -> Context) -> m ()
- lookupContextOnThread :: MonadIO m => ThreadId -> m (Maybe Context)
- attachContextOnThread :: MonadIO m => ThreadId -> Context -> m (Maybe Context)
- detachContextFromThread :: MonadIO m => ThreadId -> m (Maybe Context)
- adjustContextOnThread :: MonadIO m => ThreadId -> (Context -> Context) -> m ()
Thread-local context
getContext :: MonadIO m => m Context Source #
Retrieve a stored Context
for the current thread, or an empty context if none exists.
Warning: this can easily cause disconnected traces if libraries don't explicitly set the context on forked threads.
lookupContext :: MonadIO m => m (Maybe Context) Source #
Retrieve a stored Context
for the current thread, if it exists.
attachContext :: MonadIO m => Context -> m (Maybe Context) Source #
Store a given Context
for the current thread, returning any context previously stored.
detachContext :: MonadIO m => m (Maybe Context) Source #
Remove a stored Context
for the current thread, returning any context previously stored.
adjustContext :: MonadIO m => (Context -> Context) -> m () Source #
Alter the context on the current thread using the provided function