goingforstudying-ctrl opened a new pull request, #16889:
URL: https://github.com/apache/lucene/pull/16889

   ### Description
   
   I was looking at #13593 and the race aoli-al described is still there in 
main: `maybeStall` only stalls when `mergeSource.hasPendingMerges()` is true at 
that instant, but `IndexWriter` registers new pending merges under its own 
lock, without holding the CMS monitor. So a merge can become pending right 
between the stall check and `getNextMerge()`, and `merge()` happily spawns 
another thread even when `maxMergeCount` threads are already running. #14116 
hardened the test with a latch but the scheduler itself was never fixed.
   
   This makes the cap airtight in two spots:
   
   - A merge thread asked to schedule more work while we're at `maxMergeCount` 
now bails out of `maybeStall` even when the queue looks empty at that moment. 
It can't stall there (that would block `updateMergeThreads`), so it just 
declines to pull; the producer that registered the merge calls `executeMerge` 
right after and picks it up instead.
   - Producer threads keep the existing fast return when the queue is empty — I 
didn't want to throttle indexing purely because merges are busy — but after 
pulling a merge the cap is re-checked before the thread is spawned. Only 
producers can block in that re-check: merge threads already bailed, and the 
thread count can't grow while the CMS monitor is held, it only shrinks when 
threads are removed.
   
   The regression test reproduces the window without touching production code: 
a fake `MergeSource` materializes a late merge inside `getNextMerge`, after 
`hasPendingMerges` already evaluated false. Without the scheduler change it 
fails every time with `maxMergeCount was exceeded: 2 expected:<1> but was:<2>`, 
with the change it passes. I also ran the full `TestConcurrentMergeScheduler` 
suite (27 tests) plus `tidy` and `ecjLint`, all green. Fair warning, my first 
attempt stalled producers unconditionally on the cap and that deadlocks 
`testChangeMaxMergeCountyWhileForceMerge` (producer waits on merges parked at a 
test latch that only releases after the flush loop), which is why the producer 
side keeps the pending-gated stall.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to