Skip to content

Commit 782920c

Browse files
committed
read ahead
1 parent 25d0156 commit 782920c

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

server/src/main/java/org/elasticsearch/indices/recovery/RecoverySourceHandler.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ private class MultiFileSender extends ActionRunnable<Void> implements Closeable
697697
private final IntSupplier translogOps;
698698
private final LocalCheckpointTracker requestSeqIdTracker = new LocalCheckpointTracker(NO_OPS_PERFORMED, NO_OPS_PERFORMED);
699699
private final Semaphore semaphore = new Semaphore(0);
700+
private MultiFileReader.FileChunk currentChunk;
700701

701702
private MultiFileSender(Store store, IntSupplier translogOps, StoreFileMetaData[] files, ActionListener<Void> listener) {
702703
super(ActionListener.notifyOnce(listener));
@@ -711,21 +712,16 @@ protected void doRun() throws Exception {
711712
assert Transports.assertNotTransportThread(RecoverySourceHandler.this + "[send file chunk]");
712713
for (; ; ) {
713714
assert semaphore.availablePermits() == 0;
714-
final MultiFileReader.FileChunk chunk;
715-
try {
716-
chunk = multiFileReader.readNextChunk();
717-
} catch (IOException e) {
718-
handleErrorOnSendFiles(store, e, new StoreFileMetaData[]{ multiFileReader.currentFile() });
719-
throw e;
720-
}
721-
if (chunk == null) {
715+
final MultiFileReader.FileChunk chunk = readNextChunk();
716+
if (currentChunk == null) {
722717
semaphore.release(); // allow other threads respond if we are not done yet.
723718
if (requestSeqIdTracker.getMaxSeqNo() == requestSeqIdTracker.getProcessedCheckpoint() && semaphore.tryAcquire()) {
724719
listener.onResponse(null);
725720
}
726721
break;
727722
}
728723
final long requestSeqId = requestSeqIdTracker.generateSeqNo();
724+
currentChunk = null;
729725
cancellableThreads.execute(() ->
730726
recoveryTarget.writeFileChunk(chunk.md, chunk.position, chunk.content, chunk.lastChunk, translogOps.getAsInt(),
731727
ActionListener.wrap(
@@ -744,6 +740,7 @@ protected void doRun() throws Exception {
744740
)
745741
);
746742
if (canSendMore() == false) {
743+
readNextChunk(); // read ahead while we're waiting for acknowledgements
747744
semaphore.release();
748745
// Here we have to retry before abort to avoid a race situation where the other threads have flipped `canSendMore`
749746
// condition but they are not going to resume the sending process because this thread still holds the semaphore.
@@ -754,6 +751,19 @@ protected void doRun() throws Exception {
754751
}
755752
}
756753

754+
private MultiFileReader.FileChunk readNextChunk() throws Exception {
755+
assert semaphore.availablePermits() == 0;
756+
if (currentChunk == null) {
757+
try {
758+
currentChunk = multiFileReader.readNextChunk();
759+
} catch (IOException e) {
760+
handleErrorOnSendFiles(store, e, new StoreFileMetaData[]{multiFileReader.currentFile()});
761+
throw e;
762+
}
763+
}
764+
return currentChunk;
765+
}
766+
757767
private boolean canSendMore() {
758768
return requestSeqIdTracker.getMaxSeqNo() - requestSeqIdTracker.getProcessedCheckpoint() < maxConcurrentFileChunks;
759769
}

0 commit comments

Comments
 (0)