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:
Michael Stack 2010-04-24 17:13:50 +00:00
parent 6b626b5e5d
commit 98290fec40
4 changed files with 108 additions and 9 deletions

View File

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

View File

@ -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) {

View File

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

View File

@ -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");
}
}