HBASE-2481 Client is not getting UnknownScannerExceptions; they are being eaten
git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@937649 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6b626b5e5d
commit
98290fec40
|
@ -285,6 +285,8 @@ Release 0.21.0 - Unreleased
|
|||
(Todd Lipcon via Stack)
|
||||
HBASE-2447 LogSyncer.addToSyncQueue doesn't check if syncer is still
|
||||
running before waiting (Todd Lipcon via Stack)
|
||||
HBASE-2481 Client is not getting UnknownScannerExceptions; they are
|
||||
being eaten (Jean-Daniel Cryans via Stack)
|
||||
|
||||
IMPROVEMENTS
|
||||
HBASE-1760 Cleanup TODOs in HTable
|
||||
|
|
|
@ -916,6 +916,16 @@ public class HTable implements HTableInterface {
|
|||
values = getConnection().getRegionServerWithRetries(callable);
|
||||
}
|
||||
} catch (DoNotRetryIOException e) {
|
||||
long timeout = lastNext + scannerTimeout;
|
||||
if (e instanceof UnknownScannerException &&
|
||||
timeout < System.currentTimeMillis()) {
|
||||
long elapsed = System.currentTimeMillis() - lastNext;
|
||||
ScannerTimeoutException ex = new ScannerTimeoutException(
|
||||
elapsed + "ms passed since the last invocation, " +
|
||||
"timeout is currently set to " + scannerTimeout);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
if (cause == null || !(cause instanceof NotServingRegionException)) {
|
||||
throw e;
|
||||
|
@ -931,14 +941,6 @@ public class HTable implements HTableInterface {
|
|||
// Clear region
|
||||
this.currentRegion = null;
|
||||
continue;
|
||||
} catch (IOException e) {
|
||||
if (e instanceof UnknownScannerException &&
|
||||
lastNext + scannerTimeout < System.currentTimeMillis()) {
|
||||
ScannerTimeoutException ex = new ScannerTimeoutException();
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
lastNext = System.currentTimeMillis();
|
||||
if (values != null && values.length > 0) {
|
||||
|
|
|
@ -80,11 +80,15 @@ public class ScannerCallable extends ServerCallable<Result[]> {
|
|||
if (e instanceof RemoteException) {
|
||||
ioe = RemoteExceptionHandler.decodeRemoteException((RemoteException)e);
|
||||
}
|
||||
if (ioe != null && ioe instanceof NotServingRegionException) {
|
||||
if (ioe != null) {
|
||||
if (ioe instanceof NotServingRegionException) {
|
||||
// Throw a DNRE so that we break out of cycle of calling NSRE
|
||||
// when what we need is to open scanner against new location.
|
||||
// Attach NSRE to signal client that it needs to resetup scanner.
|
||||
throw new DoNotRetryIOException("Reset scanner", ioe);
|
||||
} else if (ioe instanceof DoNotRetryIOException) {
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rrs;
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package org.apache.hadoop.hbase.client;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.hbase.HBaseConfiguration;
|
||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Test various scanner timeout issues.
|
||||
*/
|
||||
public class TestScannerTimeout {
|
||||
|
||||
private final static HBaseTestingUtility
|
||||
TEST_UTIL = new HBaseTestingUtility();
|
||||
|
||||
final Log LOG = LogFactory.getLog(getClass());
|
||||
private final byte[] someBytes = Bytes.toBytes("f");
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
HBaseConfiguration c = TEST_UTIL.getConfiguration();
|
||||
c.setInt("hbase.regionserver.lease.period", 1000);
|
||||
TEST_UTIL.startMiniCluster(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
TEST_UTIL.shutdownMiniCluster();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we do get a ScannerTimeoutException
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void test2481() throws Exception {
|
||||
int initialCount = 10;
|
||||
HTable t = TEST_UTIL.createTable(Bytes.toBytes("t"), someBytes);
|
||||
for (int i = 0; i < initialCount; i++) {
|
||||
Put put = new Put(Bytes.toBytes(i));
|
||||
put.add(someBytes, someBytes, someBytes);
|
||||
t.put(put);
|
||||
}
|
||||
Scan scan = new Scan();
|
||||
ResultScanner r = t.getScanner(scan);
|
||||
int count = 0;
|
||||
try {
|
||||
Result res = r.next();
|
||||
while (res != null) {
|
||||
count++;
|
||||
if (count == 5) {
|
||||
Thread.sleep(1500);
|
||||
}
|
||||
res = r.next();
|
||||
}
|
||||
} catch (ScannerTimeoutException e) {
|
||||
LOG.info("Got the timeout " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
fail("We should be timing out");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue