Improve queue tail lookup fast path and reduce append lock contention#1706
Open
peter-lawrey wants to merge 3 commits intodevelopfrom
Open
Improve queue tail lookup fast path and reduce append lock contention#1706peter-lawrey wants to merge 3 commits intodevelopfrom
peter-lawrey wants to merge 3 commits intodevelopfrom
Conversation
bc0affb to
5bac48c
Compare
|
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.



This PR improves the
Long.MAX_VALUEtail-position lookup path inSingleChronicleQueueStore/SCQIndexingand reduces CPU burn under contended queue writes by using a bounded balanced pauser for write and append locks.The main behavioural change is that
sequenceForPosition(..., Long.MAX_VALUE, ...)now has a dedicated fast path that attempts to anchor the scan from the currentwritePositionrather than falling through immediately to the indexed-anchor lookup. This makes tail sequence discovery cheaper in the common case and adds clearer perf logging when the code does fall back to the slower path.What changed
Added
SCQIndexing.sequenceForMaxPosition(...)forLong.MAX_VALUEposition lookups.Uses the volatile
writePositionand sequence tracker to start from the latest known write position where possible.Retries briefly on
Sequence.NOT_FOUND_RETRYto handle races with an active writer.Yields after the first few retries to avoid starving the writer.
Falls back to the existing indexed lookup if the tracker cannot provide a usable sequence.
Adds perf-log descriptions so scan origins are distinguishable:
writePositionlastSequenceNumberAvoids restarting the
MAX_VALUEfast path after the retry budget has already been spent inlastSequenceNumber(...).Replaces
readPositionUnlimited(...)use with explicitreadLimit/readLimitToCapacity()and boundedreadPosition(...).Routes
SingleChronicleQueueStore.sequenceForPosition(..., Long.MAX_VALUE, ...)through the new dedicated fast path.Changes
writeLock()andappendLock()to usePauser.balancedUpToMillis(...), capped by the new system property:chronicle.queue.writeLockPauserMaxMs5Adds timeouts to long-running resource/contention tests.
Adjusts the rolling issue test to create more deliberate concurrent write contention using
LockSupport.parkNanos(...).Avoids resetting the security manager on Java 17+, where that API is deprecated/restricted.
Why
Long.MAX_VALUEis used as a logical “tail” position. In that case, starting from the current write position is usually much cheaper than scanning forward from an older indexed anchor. The previous path could fall into a brute-force scan, making tail lookups more expensive and harder to diagnose from logs.The new logging descriptions make it visible whether the intended
writePositionfast path was used or whether the code fell back to an indexed-anchor scan.The lock pauser change also reduces wasted CPU under contention. When the lock holder is another thread, tight spinning does not make progress; a balanced pauser gives a better busy/yield/park progression while still keeping the maximum park duration bounded.
Notes
The default write/append lock park cap is intentionally small at 5 ms and can be tuned with:
This keeps the default behaviour conservative while allowing deployments with different contention profiles to tune the lock wait strategy.