hs-opentelemetry-api
Copyright(c) Ian Duncan 2021
LicenseBSD-3
MaintainerIan Duncan
Stabilityexperimental
Portabilitynon-portable (GHC extensions)
Safe HaskellNone
LanguageHaskell2010

OpenTelemetry.Context.ThreadLocal.Propagation

Description

Haskell's green threads do not inherit thread-local state. Any time you fork a thread, directly with forkIO, or indirectly through async, mapConcurrently, etc., the child starts with an empty Context. This silently breaks trace propagation and baggage flow.

This module provides drop-in replacements for common concurrency primitives that capture the caller's Context and install it in the child thread before running the user action. The pattern mirrors Go's explicit ctx parameter and Java/Python's automatic context inheritance for child tasks.

Quick start

import OpenTelemetry.Context.ThreadLocal.Propagation

-- Instead of async work:
a <- tracedAsync work

-- Instead of forkIO work:
tid <- tracedForkIO work

-- Instead of mapConcurrently f xs:
results <- tracedMapConcurrently f xs

If you need to integrate with a concurrency primitive not covered here, use propagateContext to wrap any IO action so it inherits the current thread's context:

myCustomFork action = customFork (propagateContext action)

Since: 0.4.0.0

Synopsis

Core combinator

propagateContext :: IO a -> IO (IO a) Source #

Capture the current thread's Context and return an action that, when run in any thread, installs that context before executing the wrapped computation.

This is the fundamental building block. The other combinators in this module are thin wrappers around it.

Since: 0.4.0.0

Common concurrency wrappers

tracedForkIO :: IO () -> IO ThreadId Source #

forkIO with automatic context propagation.

Since: 0.4.0.0

tracedAsync :: IO a -> IO (Async a) Source #

async with automatic context propagation.

Since: 0.4.0.0

tracedWithAsync :: IO a -> (Async a -> IO b) -> IO b Source #

withAsync with automatic context propagation.

Since: 0.4.0.0

tracedConcurrently :: IO a -> IO b -> IO (a, b) Source #

concurrently with automatic context propagation for both branches.

Since: 0.4.0.0

tracedMapConcurrently :: Traversable t => (a -> IO b) -> t a -> IO (t b) Source #

mapConcurrently with automatic context propagation.

Each concurrent worker inherits the caller's context.

Since: 0.4.0.0

tracedForConcurrently :: Traversable t => t a -> (a -> IO b) -> IO (t b) Source #

forConcurrently with automatic context propagation.

Since: 0.4.0.0