jeho-rpls commented on code in PR #16401:
URL: https://github.com/apache/lucene/pull/16401#discussion_r3600077132


##########
lucene/core/src/test/org/apache/lucene/index/TestHnswMergeAbort.java:
##########
@@ -33,52 +36,71 @@
 import org.apache.lucene.tests.util.TestUtil;
 import org.apache.lucene.util.InfoStream;
 import org.apache.lucene.util.NamedThreadFactory;
+import org.apache.lucene.util.ThreadInterruptedException;
 
 /**
- * Tests that aborting a merge (e.g. via {@link IndexWriter#rollback()}) 
promptly interrupts HNSW
- * graph construction instead of blocking until the entire graph is built.
+ * Tests that aborting a merge (e.g. via {@link IndexWriter#rollback()}) 
interrupts HNSW graph
+ * construction instead of building the entire graph.
+ *
+ * <p>The merge thread is held at the start of the graph build until the merge 
is marked aborted,
+ * and the test then asserts that the build never ran to completion, which 
holds at any segment
+ * size. The abort exception is deliberately not asserted on: it is swallowed 
as expected control
+ * flow, and a small unchecked build can finish without ever throwing.
  */
 public class TestHnswMergeAbort extends LuceneTestCase {
 
   private static final int DIM = 96;
   private static final int SEGMENTS = 4;
-  private static final int DOCS_PER_SEGMENT = 12_000;
-  private static final int BEAM_WIDTH = 250;
+  private static final int DOCS_PER_SEGMENT = 1_000;
+  private static final int BEAM_WIDTH = 100;
+  // always build a graph, no matter how small the segment is
+  private static final int TINY_SEGMENTS_THRESHOLD = 0;
+  private static final int LIVE_DOCS_AFTER_DELETES = SEGMENTS * 
DOCS_PER_SEGMENT / 2;
 
   /**
    * Every segment carries more than {@code 
IncrementalHnswGraphMerger#DELETE_PCT_THRESHOLD}
    * deletions, so no source graph is eligible as a base and the merged graph 
is rebuilt from
    * scratch via {@code HnswGraphBuilder#addVectors}.
    */
   public void testRollbackDuringFullRebuildMerge() throws Exception {

Review Comment:
   Thanks for the review!
   
   > does this test rely on the fact that HNSW merging work is done on a 
background thread?
   
   My intent was to depend only on `rollback()` being called from a different 
thread than the merge, not on where the merge runs. The test sets that up 
explicitly, with `rollback()` on the test thread and `forceMerge` on its own 
thread.
   
   > If we had single-threaded HNSW merging (as we used to do) this would 
deadlock because the InfoStream would be waiting for the merging operation to 
be aborted, but it could not progress because it is the merging operation?
   
   I think that cycle is avoided because the release signal does not come from 
the merge side. It comes from the rollback thread, which marks every running 
merge aborted inside `IndexWriter#abortMerges` and emits the `now wait for` 
message before it ever starts waiting. The blocking branch in the test only 
fires for the HNSW `build graph` message, so the rollback thread is never held 
there. As a backstop the latch has a 2 minute timeout, so a missed release 
fails the `releasedAfterAbort` assertion instead of hanging the build.
   
   > I guess that should be OK since all of our mergers do use their own thread 
pools now
   
   It holds even without that. I swapped `ConcurrentMergeScheduler` for 
`SerialMergeScheduler` locally, so the merge runs synchronously inside 
`forceMerge`, and all three tests still pass across repeated runs.



-- 
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