Skip to content

Add dd-openfeature SDK exposure and flag evaluation pipelines - #12842

Draft
PerfectSlayer wants to merge 1 commit into
bbujon/ffe-sdk-infrafrom
bbujon/ffe-sdk-events
Draft

PerfectSlayer wants to merge 1 commit into
bbujon/ffe-sdk-infrafrom
bbujon/ffe-sdk-events

Conversation

@PerfectSlayer

@PerfectSlayer PerfectSlayer commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

What Does This Do

Adds the exposure and flag evaluation event pipelines to the dd-openfeature SDK: exposure deduplication (LRU cache), evaluation aggregation, payload building and batching over the connector event transport. Includes the JMH benchmarks.

Motivation

Event batching stays in the SDK; the agent only forwards payloads (APMLP-1512).

Additional Notes

The logic is ported almost entirely from the agent feature-flagging-lib / feature-flagging-bootstrap modules. Review carefully the two pipelines, now sending through the connector EventTransport instead of the agent EVP publisher, and the JSON serialization, moved from Moshi to hand-written Jackson streaming. Everything else is a package move.

New files
File Notes
exposure/ExposuresRequestTest Wire shape tests of the hand-written exposure JSON: serial_id present / zero / absent, context and subject attributes
Moved, package rename only (no logic change)
  • exposure/Allocation, exposure/Flag, exposure/Subject, exposure/Variant, flagevaluation/FlagEvalEvent (from bootstrap datadog.trace.api.featureflag.*)
  • exposure/ExposureEvent: also drops the 5-arg convenience constructor, serial_id is passed explicitly
  • exposure/ExposureCache (from feature-flagging-lib)
  • flagevaluation/FlagEvaluationAggregator: agent HashingUtils replaced by equivalent private helpers
  • Tests: exposure/LRUExposureCacheTest (passes a null serial id), flagevaluation/FlagEvaluationAggregatorTest
  • JMH: FlagEvaluationHotPathBenchmark, FlagEvaluationEnqueueContentionBenchmark, now building FlagEvaluationPipeline with a no-op EventTransport and HealthMetrics.NOOP instead of the agent Config / BackendApiFactory
Moved with significant changes
New file Master origin Changes
exposure/ExposurePipeline lib ExposureWriterImpl Posts to the exposures route through EventTransport instead of FeatureFlagEvpPublisher. Plain Consumer<ExposureEvent>, no gateway listener registration. SDK EventQueue replaces the JCTools queue, RuntimeServices.newThread replaces AgentThreadFactory. "EVP proxy unavailable" startup check removed. Dedup, batching and flush logic unchanged
exposure/ExposuresRequest bootstrap exposure/ExposuresRequest Same DTO plus serialize() with Jackson streaming (JsonWriting) instead of Moshi reflection; null subject.id, subject.attributes and serial_id omitted
exposure/LRUExposureCache lib LRUExposureCache Agent LRUCache replaced by an access-ordered LinkedHashMap
flagevaluation/FlagEvaluationPipeline lib FlagEvaluationWriterImpl Posts to the flagevaluation route through EventTransport; agentless / proxy fallback now lives in the transport. Health counters through RuntimeServices.countMetric instead of CoreMetricCollector. EventQueue and RuntimeServices.newThread replace JCTools and the agent thread. Gateway coupling (registration, enqueue gate, deregistration), EVP proxy fail-fast, error callback and test-only factories removed. Payload limit hard-coded to 5 MiB (was EvpProxy.PAYLOAD_SIZE_LIMIT_BYTES). Aggregation, final flush and drop accounting unchanged
flagevaluation/FlagEvaluationWriter bootstrap flagevaluation/FlagEvaluationWriter Narrowed to the producer API (enqueue, hasCapacityForEnqueue, countPreQueueOverflow, countContextTruncated); lifecycle moved to FlagEvaluationPipeline
flagevaluation/FlagEvaluationPayloads lib FlagEvaluationPayloads Moshi adapters and request DTO replaced by Jackson streaming (null optionals omitted). SHA-256 hashTargetingKey inlined from ULeb128Encoder, same algorithm
exposure/ExposurePipelineTest lib ExposureWriterTests Rewritten against a capturing EventTransport. Agentless, retry and EVP proxy tests dropped (now transport concerns). Added close, wire shape and non-finite attribute tests
flagevaluation/FlagEvaluationPipelineTest lib FlagEvaluationWriterImplTest Agent-only tests dropped (direct intake, gateway gate / consent / registration, EVP fail-fast, SCO constructor). Added non-finite context number serialization test
flagevaluation/FlagEvaluationTestSupport lib FlagEvaluationTestSupport Mockito BackendApi / OkHttp capture replaced by a CapturingTransport and RecordingMetrics; Moshi replaced by JsonReading
Shared files
  • dd-openfeature/build.gradle.kts: applies dd-trace-java.jmh-conventions for the moved benchmarks

Stack

The full change is in #12709. It was split into this stack to ease the review.

  1. Resolve Feature Flags enablement from instrumenter config #12845
  2. Add dd-openfeature SDK flag configuration and evaluation core #12840
  3. Add dd-openfeature SDK settings and configuration delivery #12841
  4. Add dd-openfeature SDK exposure and flag evaluation pipelines #12842 👈 this PR
  5. Add dd-openfeature SDK OpenFeature provider #12843
  6. Connect the dd-openfeature SDK to the agent #12844
  7. Add agentless and standalone OpenFeature smoke tests #12846

Jira ticket: APMLP-1512

🤖 Generated with Claude Code

@datadog-prod-us1-5

This comment has been minimized.

@dd-octo-sts

dd-octo-sts Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 14.00 s 13.96 s [-0.6%; +1.1%] (no difference)
startup:insecure-bank:tracing:Agent 12.93 s 12.99 s [-1.3%; +0.4%] (no difference)
startup:petclinic:appsec:Agent 17.03 s 16.86 s [+0.2%; +1.8%] (maybe worse)
startup:petclinic:iast:Agent 16.85 s 16.40 s [-1.4%; +6.8%] (no difference)
startup:petclinic:profiling:Agent 16.15 s 16.71 s [-7.6%; +0.9%] (no difference)
startup:petclinic:sca:Agent 17.05 s 16.34 s [+0.0%; +8.7%] (maybe worse)
startup:petclinic:tracing:Agent 16.05 s 15.97 s [-0.3%; +1.3%] (no difference)

Commit: d943b6b6 · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

Add the exposure and flag evaluation event pipelines: deduplication,
aggregation, payload building and batching over the event transport.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: openfeature OpenFeature tag: ai generated Largely based on code generated by an AI or LLM tag: no release notes Changes to exclude from release notes type: feature Enhancements and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant