diwu-sf commented on code in PR #16923:
URL: https://github.com/apache/lucene/pull/16923#discussion_r4451980394


##########
lucene/core/src/java/org/apache/lucene/index/StandardDirectoryReader.java:
##########
@@ -463,10 +463,12 @@ private DirectoryReader doOpenFromWriter(IndexCommit 
commit, ExecutorService exe
       return null;
     }
 
-    DirectoryReader reader = writer.getReader(applyAllDeletes, 
writeAllDeletes);
+    StandardDirectoryReader reader = writer.getReader(applyAllDeletes, 
writeAllDeletes);
 
-    // If in fact no changes took place, return null:
-    if (reader.getVersion() == segmentInfos.getVersion()) {
+    // If in fact no changes took place, return null. A commit that was 
syncing files when this
+    // reader was opened changes the referenced segments_N once it completes, 
but not the version:
+    if (reader.getVersion() == segmentInfos.getVersion()
+        && reader.segmentInfos.getLastGeneration() == 
segmentInfos.getLastGeneration()) {

Review Comment:
   Thanks, you're right. A reader opened while a commit was still in progress, 
and the reader opened right after it, could end up with the same version. 
`SearcherLifetimeManager` can't handle that, and the test failure you saw comes 
from it.
   
   I couldn't reproduce it with your seed on my machine, so I wrote a test that 
pauses the commit at the right moment. It now fails every time on the old code.
   
   Fixed by bumping the version, as you suggested, with one change: I only bump 
it if a reader was opened while the commit was in progress. Bumping on every 
commit breaks an existing test (`testAddCloseOpen`), which expects a reader 
opened right after a commit to have the same version as that commit.
   
   One side effect: after a commit during which a reader was opened, readers 
opened afterwards have a version one higher than the commit on disk. With 
frequent refreshes and slow disk syncs, that's most commits. Once the writer is 
closed, such a reader says it's out of date even though its data is correct; a 
new reader opened from the directory has the same data. There's a test and a 
code comment for this, and the PR description explains it.
   
   Also, a reader opened during a commit was still reported as current once the 
writer was closed, because `isCurrent()` then only compares versions with the 
latest commit on disk. It now also checks that the reader points at that 
commit, and there's a test for it.
   
   I moved the test into a new `TestNRTReaderDuringCommit` and added more 
cases: two-step commits (`prepareCommit()` then `commit()`), changes made 
during a commit, a commit that fails, your `SearcherLifetimeManager` case, 
making sure commits with no changes don't change the version, and a randomized 
test. The tests pause commits with latches rather than sleeps. The randomized 
test fails every time on the old code and passes with the fix. `./gradlew 
:lucene:core:check` and the nightly replication tests pass.
   
   



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