sdk/metric: add internal finish-aware Sum lifecycle - #8925
Draft
MrAlias wants to merge 17 commits into
Draft
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #8925 +/- ##
======================================
Coverage 88.5% 88.6%
======================================
Files 333 335 +2
Lines 21101 21353 +252
======================================
+ Hits 18687 18921 +234
- Misses 2414 2432 +18
🚀 New features to boost your workflow:
|
Introduce an internal Sum implementation that can retire individual attribute series after their final measurement while preserving cumulative and delta collection semantics. Keep recording free of mutex acquisition by combining the lifecycle state and in-flight writer count in one atomic value. Reclaim retired cardinality slots, retain overflow protection, and prevent shutdown from recreating series. Cover lifecycle transitions, timestamp behavior, collection, cardinality, exemplars, shutdown, concurrency, and recording performance.
Add the required Unreleased changelog entry so the lifecycle work is represented in the module release notes. Reshape the recording benchmarks into reproducible stable and finish-aware cases for both serial and parallel execution. This allows benchstat to report the feature's synchronization cost from committed code.
Exercise retirement while a measurement remains in flight and verify that cleanup waits for the writer before making the series terminal. Cover repeated identity-safe deletion and collection of retired points. These paths preserve cardinality accounting and raise patch coverage above the repository threshold.
Document why lifecycle state and admitted measurement count share one atomic value. This makes the lock-free admission guarantee easier to understand and maintain.
Name each state after the series lifecycle it describes. This avoids suggesting that an active series has a finish operation in progress.
Rename lifecycle methods as an acquire/release pair and document the successful acquisition obligation. This makes the Boolean result and writer-count ownership explicit without changing the hot path.
Document the unsigned decrement and the acquisition invariant that prevents it from borrowing into the packed lifecycle state.
Explain why the lifecycle remains active across the separate check and atomic update, and how concurrent writer-count changes are preserved.
Name the collection result as a decision and remove the ambiguous finish prefix from its mode. This distinguishes collection policy and outcomes from the lifecycle's collecting state.
Replace the collection-mode control parameter with explicit cumulative and delta entry points. This makes supported behavior visible and lets the API prevent invalid collection modes.
Move finish-aware series coordination behind a dedicated internal package. Export only the supported lifecycle protocol and use phase tokens to make measurement release and collection completion explicit. The lifecycle now owns serialization, preventing callers from reaching packed-state helpers.
MrAlias
force-pushed
the
finish-sum-lifecycle
branch
from
September 4, 2026 19:54
2cdaf59 to
5971006
Compare
Track lifecycle state and admitted writers independently so collection cannot reset a writer count that a stale measurement later decrements. Reserve a new series' first measurement before publishing that series so collection cannot emit an empty point during its creation.
Distinguish series routed to shared cardinality overflow from ordinary series whose attributes equal the overflow marker. Promote a colliding ordinary series when it later becomes the shared overflow destination so Finish remains disabled only for genuinely shared state.
Keep finish Sum value construction separate from lifecycle admission. The map creation callback now reserves the first measurement immediately before publishing the point, making the publication ordering explicit while preserving collection safety.
Prevent a stale overflow check from finishing a series after it becomes shared cardinality overflow. Promotion now admits its triggering measurement while serialized with Finish, preserving the shared series through cumulative collection without locking ordinary measurements.
Represent shared overflow as a lifecycle state so promotion and Finish compete through one atomic transition. This prevents a delayed Finish from retiring shared overflow without putting a mutex on the measurement path. Exercise the real marker-promotion path and benchmark both the transition and subsequent shared-overflow measurements.
Return a Boolean from lifecycle collection methods so callers reject a retired lifetime before passing its Collection token downstream. Every token that reaches the aggregate collector is now valid and completed exactly once. This removes the overloaded ShouldEmit contract and makes collection lock ownership visible at the lifecycle boundary.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sdk/metric/internal/finishpackageFinish, so shared overflow can never be retired by a stale finishThis establishes the internal lifecycle needed for #8905. It intentionally does not expose SDK activation or connect
metricx.Finisher; that wiring will follow after this implementation is reviewed.The existing stable Sum implementation and its recording path are unchanged.
Performance
BenchmarkFinishSumMeasureis committed in this PR and directly compares the stable (finish=false) and finish-aware (finish=true) recording paths with a prebuilt attribute set. The following rawbenchstatoutput was produced from the pushed commita749b3b0f:BenchmarkFinishSumOverflowMeasurementseparately measures the one-time marker-to-shared-overflow promotion and later measurements of the promoted point. The identical benchmark now committed ata749b3b0fwas run against the mutex implementation at0e2a8f49eand the atomic lifecycle implementation ata749b3b0f:Ordinary measurements, the promotion measurement, and subsequent shared-overflow measurements acquire no mutex. Promotion and
Finishinstead compete through one lifecycle CAS. Finish, collection, and shutdown control transitions remain serialized by each series lifecycle.Validation
make precommitsdk/metricmoduleFinishBuilds on #8906.