From 0cd2a05ab84d6734d3e6a4151721781876f7f63a Mon Sep 17 00:00:00 2001 From: Keith Turner Date: Thu, 6 Feb 2025 22:54:40 +0000 Subject: [PATCH] avoid clearing server in cache when scanner closed and interrupted When the thread running an accumulo scanner is interrupted it may cause the server the scanner was reading from to be cleared from the cache. This can be disruptive in the case where the server is fine. This change makes a narrow exception to clearing the server from the cache for the case where the scanner was closed and an interrupt was seen. The reason this is so narrow is to avoid failing to invalidate the cache in the case where there is actually a problem with the server. --- .../accumulo/core/clientImpl/ScannerIterator.java | 2 ++ .../accumulo/core/clientImpl/ThriftScanner.java | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/clientImpl/ScannerIterator.java b/core/src/main/java/org/apache/accumulo/core/clientImpl/ScannerIterator.java index bf8f01687f8..d1eca1b1987 100644 --- a/core/src/main/java/org/apache/accumulo/core/clientImpl/ScannerIterator.java +++ b/core/src/main/java/org/apache/accumulo/core/clientImpl/ScannerIterator.java @@ -124,6 +124,8 @@ public Entry next() { } void close() { + // setting this so that some errors can be ignored + scanState.closeInitiated = true; // run actual close operation in the background so this does not block. context.executeCleanupTask(() -> { synchronized (scanState) { diff --git a/core/src/main/java/org/apache/accumulo/core/clientImpl/ThriftScanner.java b/core/src/main/java/org/apache/accumulo/core/clientImpl/ThriftScanner.java index 5894e3f2df7..0447e5d423b 100644 --- a/core/src/main/java/org/apache/accumulo/core/clientImpl/ThriftScanner.java +++ b/core/src/main/java/org/apache/accumulo/core/clientImpl/ThriftScanner.java @@ -22,6 +22,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import java.io.IOException; +import java.io.InterruptedIOException; import java.security.SecureRandom; import java.time.Duration; import java.util.ArrayList; @@ -212,6 +213,8 @@ public static class ScanState { Duration busyTimeout; + volatile boolean closeInitiated = false; + TabletLocation getErrorLocation() { return prevLoc; } @@ -508,8 +511,13 @@ public static List scan(ClientContext context, ScanState scanState, Du TraceUtil.setException(child2, e, false); sleepMillis = pause(sleepMillis, maxSleepTime, scanState.runOnScanServer); } catch (TException e) { - TabletLocator.getLocator(context, scanState.tableId).invalidateCache(context, - loc.tablet_location); + boolean wasInterruptedAfterClose = + e.getCause() != null && e.getCause().getClass().equals(InterruptedIOException.class) + && scanState.closeInitiated; + if (!wasInterruptedAfterClose) { + TabletLocator.getLocator(context, scanState.tableId).invalidateCache(context, + loc.tablet_location); + } error = "Scan failed, thrift error " + e.getClass().getName() + " " + e.getMessage() + " " + scanState.getErrorLocation(); if (!error.equals(lastError)) {