Skip to content

Conversation

@yaauie
Copy link
Member

@yaauie yaauie commented Sep 25, 2025

Release notes

[rn: skip]

What does this PR do?

Improves the accuracy of ConcurrentLiveTimerMetric in cases where many threads are contending to record their timings.

When using AtomicReference#getAndUpdate(UnaryOperator), the provided operator may be run multiple times in cases where another thread has "won" the update. By moving the capture of the timestamp out of this block, we ensure an accurate recording for the completion time of the measurement and prevent it from including the time contending to write the measurement.

Why is it important/What is the impact to the user?

No major user impact, but slightly improves the accuracy of timer-type metrics.

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • [ ] I have made corresponding changes to the documentation
  • [ ] I have made corresponding change to the default configuration files (and/or docker env variables)
  • [ ] I have added tests that prove my fix is effective or that my feature works

Author's Checklist

  • [ ]

How to test this PR locally

Verification relies on the existing test coverage for ConcurrentLiveTimerMetric, along with an understanding of what bringing the call to LongSupplier#getAsLong out of block means when the block needs to be re-run.

excludes contention for recording timing from the timing
by locking in the completion time before attempting to
record it
@github-actions
Copy link
Contributor

🤖 GitHub comments

Expand to view the GitHub comments

Just comment with:

  • run docs-build : Re-trigger the docs validation. (use unformatted text in the comment!)

@mergify
Copy link
Contributor

mergify bot commented Sep 25, 2025

This pull request does not have a backport label. Could you fix it @yaauie? 🙏
To fixup this pull request, you need to add the backport labels for the needed
branches, such as:

  • backport-8./d is the label to automatically backport to the 8./d branch. /d is the digit.
  • If no backport is necessary, please add the backport-skip label

public <T, E extends Throwable> T time(ExceptionalSupplier<T, E> exceptionalSupplier) throws E {
try {
trackedMillisState.getAndUpdate(TrackedMillisState::withIncrementedConcurrency);
trackedMillisState.getAndUpdate(existing -> existing.withIncrementedConcurrency(nanoTimeSupplier.getAsLong()));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: the nanoTimeSupplier.getAsLong() for recording the start time still occurs inside the UnaryConsumer because if this thread loses and is retried, we don't want to record an old start time.

Copy link
Member

@robbavey robbavey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the unused imports, LGTM

@elastic-sonarqube
Copy link

Quality Gate passed Quality Gate passed

Issues
0 New issues
0 Fixed issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarQube

@elasticmachine
Copy link
Collaborator

@yaauie yaauie merged commit 88b853a into elastic:main Sep 29, 2025
12 checks passed
v1v pushed a commit that referenced this pull request Oct 21, 2025
* metric: improve accuracy of timer metric

excludes contention for recording timing from the timing
by locking in the completion time before attempting to
record it

* remove unused imports
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants