Documentation
¶
Index ¶
- Constants
- func CtxWithValue(parent context.Context, key, val any) context.Context
- func Enabled() bool
- func GLSActivate(ctxp *context.Context, key, val any, pop *GLSPopperCell)
- func GLSDeactivate(reclaimable *atomic.Bool, pop *GLSPopperCell)
- func GLSPopFunc(key any) func()
- func GLSPopValue(key any) any
- func GLSReset(reclaimable *atomic.Bool, pop *GLSPopperCell)
- func GLSStackDepth() int
- func MockGLS() func()
- func MockGLSPerGoroutine() func()
- func WrapContext(ctx context.Context) context.Context
- type GLSPopper
- type GLSPopperCell
Constants ¶
const Version = ""
The version of the orchestrion binary used to build the current binary, or blank if the current binary was not built using orchestrion.
Variables ¶
This section is empty.
Functions ¶
func CtxWithValue ¶
CtxWithValue runs context.WithValue, adds the result to the GLS slot of orchestrion, and returns it. If orchestrion is not enabled, it will run context.WithValue and return the result. Since we don't support cross-goroutine switch of the GLS we still run context.WithValue in the case we are switching goroutines.
func Enabled ¶
func Enabled() bool
Enabled returns whether the current build was compiled with orchestrion or not.
func GLSActivate ¶
func GLSActivate(ctxp *context.Context, key, val any, pop *GLSPopperCell)
GLSActivate is woven into span/operation activation (the tracer's ContextWithSpan and dyngo's RegisterOperation). It pushes val onto the current goroutine's GLS stack under key and records a goroutine-scoped popper into pop, capturing it only on the first activation so re-activating the same span/operation does not overwrite the popper its matching GLSDeactivate will run. The captured popper pops the top of the pushing goroutine's stack and is a no-op on any other goroutine, so a cross-goroutine finish can never corrupt an unrelated goroutine's stack.
When ctxp is non-nil the parent context is wrapped (via WrapContext) so the returned context is also GLS-aware, matching the former in-source CtxWithValue. Everything is a no-op when orchestrion is disabled.
Grouping the wrap, push and popper-capture here keeps the injected templates a single call and the logic unit-testable in plain go test. The companions are GLSDeactivate (finish) and GLSReset (span-pool reuse).
func GLSDeactivate ¶
func GLSDeactivate(reclaimable *atomic.Bool, pop *GLSPopperCell)
GLSDeactivate releases a span's GLS entry on finish. It marks the span reclaimable (so a cross-goroutine finish, whose popper is a no-op here, is still cleaned up by contextStack.Push on its next push) and invokes the captured popper exactly once, clearing it so a repeated finish does not pop again. reclaimable and pop are the fields orchestrion injects onto the span; passing them by pointer lets injected span-finish advice deactivate in one call.
func GLSPopFunc ¶ added in v2.7.0
func GLSPopFunc(key any) func()
GLSPopFunc returns a function that pops key from the GLS context stack of the goroutine that called GLSPopFunc. The returned function is safe to call from any goroutine: it compares the current goroutine's GLS contextStack pointer with the one captured at creation time and only pops if they match (i.e., same goroutine). On a different goroutine the pop is a no-op, preventing accidental corruption of another goroutine's GLS state.
func GLSPopValue ¶
GLSPopValue pops the value from the GLS slot of orchestrion and returns it. Using context.Context values usually does not require to pop any stack because the copy of each previous context makes the local variable in the scope disappear when the current function ends. But the GLS is a semi-global variable that can be accessed from any function in the stack, so we need to pop the value when we are done with it.
func GLSReset ¶
func GLSReset(reclaimable *atomic.Bool, pop *GLSPopperCell)
GLSReset clears the GLS bookkeeping fields orchestrion injects onto a span so that a span returned to the tracer's pool and later reused is never treated as reclaimable or left carrying a stale popper. It is woven into Span.clear. The reclaimable argument may be nil (dyngo operations carry no reclaim flag).
func GLSStackDepth ¶ added in v2.7.0
func GLSStackDepth() int
GLSStackDepth returns the total number of entries in the current goroutine's GLS context stack. Returns 0 if orchestrion is not enabled. This is intended for use in tests to detect GLS leaks.
func MockGLS ¶ added in v2.7.0
func MockGLS() func()
MockGLS sets up a mock GLS for testing and returns a cleanup function that restores the original state. It enables orchestrion and configures a fresh contextStack accessible via the standard getDDGLS/setDDGLS functions.
This is intended for use by tests in packages that depend on orchestrion (e.g., internal, ddtrace/tracer). Follows the same pattern as telemetry.MockClient in internal/telemetry/globalclient.go.
Tests using MockGLS must NOT use t.Parallel, as it mutates package-level variables without synchronization.
func MockGLSPerGoroutine ¶ added in v2.7.0
func MockGLSPerGoroutine() func()
MockGLSPerGoroutine sets up per-goroutine GLS isolation for testing. Unlike MockGLS which uses a single shared GLS, this mock uses goroutine IDs to give each goroutine its own independent contextStack, simulating the real orchestrion runtime behavior where each runtime.g has its own GLS slot.
This is required for tests that spawn goroutines and need to verify cross-goroutine GLS behavior (e.g., GLSPopFunc no-op on wrong goroutine).
Tests using MockGLSPerGoroutine must NOT use t.Parallel, as it mutates package-level variables without synchronization.
Types ¶
type GLSPopper ¶
type GLSPopper func()
GLSPopper releases a span's GLS entry. It is the goroutine-scoped popper captured at activation (via GLSPopFunc) and stored, atomically, in a GLSPopperCell.
type GLSPopperCell ¶
type GLSPopperCell struct {
// contains filtered or unexported fields
}
GLSPopperCell holds a GLSPopper atomically. It is the type orchestrion injects as the popper field on Span and dyngo's operation (via add-struct-field, which requires a named type). Storing the popper in an atomic pointer makes the woven paths race-free: GLSDeactivate (woven into Span.Finish) and GLSReset (woven into Span.clear) can run concurrently on the same field when a span is finished on one goroutine while the tracer's span pool recycles it on another, and a repeated finish must run the popper at most once. The zero value is ready to use; a nil inner pointer means no popper is currently captured.
Directories
¶
| Path | Synopsis |
|---|---|
|
This program generates the `orchestrion.tool.go` file at `./orchestrion/all` from the root of the repository, which contains the necessary directives to facilitate onboarding of orchestrion.
|
This program generates the `orchestrion.tool.go` file at `./orchestrion/all` from the root of the repository, which contains the necessary directives to facilitate onboarding of orchestrion. |