Use Stopwatch for LockableContext acquire timeouts#1772
Merged
kevin-montrose merged 3 commits intoMay 18, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates Tsavorite's manual lock-acquisition retry loops to measure elapsed timeout using Stopwatch instead of DateTime.UtcNow, so lock and lock-promotion timeouts are based on monotonic time and are no longer affected by wall-clock adjustments.
Changes:
- Replaced wall-clock timeout tracking in
DoManualTryLockwithStopwatch.GetTimestamp()/Stopwatch.GetElapsedTime. - Replaced wall-clock timeout tracking in
DoManualTryPromoteLockwith the same monotonic timing pattern.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
kevin-montrose
requested changes
May 8, 2026
Contributor
|
This LGTM - please fix conflicts and get a green CI run. |
…-stopwatch-timeout
kevin-montrose
approved these changes
May 18, 2026
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.
DoManualTryLockandDoManualTryPromoteLockuseDateTime.UtcNow.Ticksdeltas to enforce the caller-suppliedTimeSpan timeout. A wall-clock adjustment (NTP step, manual change) lands the comparison on a perturbed value: a backward step keeps retrying past the intended deadline, a forward step gives up early. Both methods are pure local timeout loops — no protocol or persistence concerns — so monotonic time is the right primitive.Switch to
Stopwatch.GetTimestamp()/Stopwatch.GetElapsedTimefor the elapsed-time math. Behavior under stable clocks is unchanged; the timeout contract is now enforced against a clock that can't move sideways.Same NTP-resilience reasoning was applied recently in dotnet/runtime#127303 for
EventCounter's polling timer.Changes
DoManualTryLockandDoManualTryPromoteLockinLockableContext.cscaptureStopwatch.GetTimestamp()at entry and gate retries onStopwatch.GetElapsedTime(startTimestamp) > timeout.Test plan
TryLockTimeSpanLimitTest,TryLockCancellationTest,TryPromoteLockTimeSpanLimitTest,TryPromoteLockCancellationTestpass onnet8.0andnet10.0.Tsavorite.corebuilds clean.