From df2d368786eb0b4d11bc2a59c38b246203316fa4 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 1 Sep 2026 16:09:21 -0400 Subject: [PATCH] Add @ForegroundSafe / @BackgroundOnly marker annotations Documentation-and-tooling markers declaring whether code is cheap enough for application (foreground) threads or must be confined to a background thread the tracer paces itself. No application to real code yet and no checker -- just the annotation types, following the Strategy/StrategyConsumer marker convention (APMLP-1543). --- .../trace/api/function/BackgroundOnly.java | 33 +++++++++++++++++ .../trace/api/function/ForegroundSafe.java | 36 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 internal-api/src/main/java/datadog/trace/api/function/BackgroundOnly.java create mode 100644 internal-api/src/main/java/datadog/trace/api/function/ForegroundSafe.java diff --git a/internal-api/src/main/java/datadog/trace/api/function/BackgroundOnly.java b/internal-api/src/main/java/datadog/trace/api/function/BackgroundOnly.java new file mode 100644 index 00000000000..242652be53d --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/function/BackgroundOnly.java @@ -0,0 +1,33 @@ +package datadog.trace.api.function; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks code that must be confined to a background thread the tracer owns and paces itself -- e.g. + * serialization, stats aggregation, or eviction -- and must never be reached from an application + * thread (the foreground; see {@link ForegroundSafe}), where its cost would become customer-visible + * latency instead. + * + *

This is a documentation-and-tooling marker; it changes no behavior. It exists to telegraph the + * constraint to readers and to give a future checker (see {@code APMLP-1645}) something to verify + * -- that no {@code @BackgroundOnly} code is reachable from a foreground call site. The discipline + * it names is not yet enforced; hold to it by hand until the checker lands. + * + *

The two markers are not symmetric -- see {@link ForegroundSafe} for why it, not this + * one, is the strictly stronger guarantee. + * + *

On a type ({@link ElementType#TYPE}): every method of this type is background-only + * unless a method-level {@link ForegroundSafe} widens it. + * + *

On a method ({@link ElementType#METHOD}): this method specifically is background-only, + * regardless of what the enclosing type declares -- a method-level marker always wins over the + * type-level one. + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface BackgroundOnly {} diff --git a/internal-api/src/main/java/datadog/trace/api/function/ForegroundSafe.java b/internal-api/src/main/java/datadog/trace/api/function/ForegroundSafe.java new file mode 100644 index 00000000000..b1c0985dc3c --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/function/ForegroundSafe.java @@ -0,0 +1,36 @@ +package datadog.trace.api.function; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks code cheap enough to call from an application thread (the foreground) -- the request or + * transaction thread the instrumented application itself is running, where any added cost is + * customer-visible latency, as opposed to a background thread the tracer owns and paces itself (see + * {@link BackgroundOnly}). + * + *

This is a documentation-and-tooling marker; it changes no behavior. It exists to telegraph the + * guarantee to readers and to give a future checker (see {@code APMLP-1645}) something to verify -- + * that no {@link BackgroundOnly} code is reachable from a foreground call site. The discipline it + * names is not yet enforced; hold to it by hand until the checker lands. + * + *

The two markers are not symmetric. {@code @ForegroundSafe} is the strictly stronger + * guarantee: code cheap enough for the foreground is automatically fine to call from a background + * thread too, so a {@code @ForegroundSafe} type or method may be called from either. {@link + * BackgroundOnly} code carries no such guarantee and must never be reached from a foreground call + * site. + * + *

On a type ({@link ElementType#TYPE}): every method of this type is foreground-safe + * unless a method-level {@link BackgroundOnly} narrows it. + * + *

On a method ({@link ElementType#METHOD}): this method specifically is foreground-safe, + * regardless of what the enclosing type declares -- a method-level marker always wins over the + * type-level one. + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface ForegroundSafe {}