From fa97027e80a641b16247008e10fffe35fbe05fa4 Mon Sep 17 00:00:00 2001 From: Phil Yang Date: Tue, 26 Apr 2016 17:45:27 +0800 Subject: [PATCH] HBASE-15645 hbase.rpc.timeout is not used in operations of HTable --- .../org/apache/hadoop/hbase/client/HBaseAdmin.java | 14 ++++--- .../org/apache/hadoop/hbase/client/HTable.java | 46 ++++++++++++++++------ .../org/apache/hadoop/hbase/client/HTablePool.java | 16 ++++++++ .../hadoop/hbase/client/RpcRetryingCaller.java | 16 ++++++-- .../hbase/client/RpcRetryingCallerFactory.java | 25 +++++++++++- .../client/StatsTrackingRpcRetryingCaller.java | 2 +- .../java/org/apache/hadoop/hbase/client/Table.java | 31 +++++++++++++++ .../hbase/client/TestFastFailWithoutTestUtil.java | 2 +- .../java/org/apache/hadoop/hbase/HConstants.java | 4 +- hbase-common/src/main/resources/hbase-default.xml | 11 +++++- .../hadoop/hbase/rest/client/RemoteHTable.java | 16 ++++++++ .../apache/hadoop/hbase/client/HTableWrapper.java | 16 ++++++++ .../org/apache/hadoop/hbase/client/TestHCM.java | 26 +++++++++++- 13 files changed, 197 insertions(+), 28 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index 3cdf5cd..e4e6beb 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -211,6 +211,7 @@ public class HBaseAdmin implements Admin { private boolean cleanupConnectionOnClose = false; // close the connection in close() private boolean closed = false; private int operationTimeout; + private int rpcTimeout; private RpcRetryingCallerFactory rpcCallerFactory; private RpcControllerFactory rpcControllerFactory; @@ -269,6 +270,8 @@ public class HBaseAdmin implements Admin { "hbase.client.retries.longer.multiplier", 10); this.operationTimeout = this.conf.getInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT); + this.rpcTimeout = this.conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, + HConstants.DEFAULT_HBASE_RPC_TIMEOUT); this.syncWaitTimeout = this.conf.getInt( "hbase.client.sync.wait.timeout.msec", 10 * 60000); // 10min @@ -538,12 +541,12 @@ public class HBaseAdmin implements Admin { @Override public HTableDescriptor getTableDescriptor(final TableName tableName) throws IOException { return getTableDescriptor(tableName, getConnection(), rpcCallerFactory, rpcControllerFactory, - operationTimeout); + operationTimeout, rpcTimeout); } static HTableDescriptor getTableDescriptor(final TableName tableName, HConnection connection, RpcRetryingCallerFactory rpcCallerFactory, final RpcControllerFactory rpcControllerFactory, - int operationTimeout) throws IOException { + int operationTimeout, int rpcTimeout) throws IOException { if (tableName == null) return null; HTableDescriptor htd = executeCallable(new MasterCallable(connection) { @Override @@ -560,7 +563,7 @@ public class HBaseAdmin implements Admin { } return null; } - }, rpcCallerFactory, operationTimeout); + }, rpcCallerFactory, operationTimeout, rpcTimeout); if (htd != null) { return htd; } @@ -4213,8 +4216,9 @@ public class HBaseAdmin implements Admin { } private static & Closeable, V> V executeCallable(C callable, - RpcRetryingCallerFactory rpcCallerFactory, int operationTimeout) throws IOException { - RpcRetryingCaller caller = rpcCallerFactory.newCaller(); + RpcRetryingCallerFactory rpcCallerFactory, int operationTimeout, int rpcTimeout) + throws IOException { + RpcRetryingCaller caller = rpcCallerFactory.newCaller(rpcTimeout); try { return caller.callWithRetries(callable, operationTimeout); } finally { diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java index 750edaa..c5ead39 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java @@ -125,7 +125,8 @@ public class HTable implements HTableInterface, RegionLocator { protected int scannerCaching; protected long scannerMaxResultSize; private ExecutorService pool; // For Multi & Scan - private int operationTimeout; + private int operationTimeout; // global timeout for each blocking method with retrying rpc + private int rpcTimeout; // timeout for each rpc request private final boolean cleanupPoolOnClose; // shutdown the pool in close() private final boolean cleanupConnectionOnClose; // close the connection in close() private Consistency defaultConsistency = Consistency.STRONG; @@ -354,9 +355,10 @@ public class HTable implements HTableInterface, RegionLocator { if (connConfiguration == null) { connConfiguration = new ConnectionConfiguration(configuration); } - this.operationTimeout = tableName.isSystemTable() ? connConfiguration.getMetaOperationTimeout() : connConfiguration.getOperationTimeout(); + this.rpcTimeout = configuration.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, + HConstants.DEFAULT_HBASE_RPC_TIMEOUT); this.scannerCaching = connConfiguration.getScannerCaching(); this.scannerMaxResultSize = connConfiguration.getScannerMaxResultSize(); if (this.rpcCallerFactory == null) { @@ -572,7 +574,7 @@ public class HTable implements HTableInterface, RegionLocator { @Override public HTableDescriptor getTableDescriptor() throws IOException { HTableDescriptor htd = HBaseAdmin.getTableDescriptor(tableName, connection, - rpcCallerFactory, rpcControllerFactory, operationTimeout); + rpcCallerFactory, rpcControllerFactory, operationTimeout, rpcTimeout); if (htd != null) { return new UnmodifyableHTableDescriptor(htd); } @@ -754,7 +756,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory.newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory.newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -859,7 +862,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory.newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory.newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } // Call that takes into account the replica @@ -975,7 +979,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); + rpcCallerFactory. newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -1092,7 +1097,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory. newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -1123,7 +1129,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory. newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -1193,7 +1200,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory. newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -1222,7 +1230,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory. newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -1252,7 +1261,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory. newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -1281,7 +1291,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory. newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -1311,7 +1322,8 @@ public class HTable implements HTableInterface, RegionLocator { } } }; - return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); + return rpcCallerFactory. newCaller(rpcTimeout).callWithRetries(callable, + this.operationTimeout); } /** @@ -1765,6 +1777,14 @@ public class HTable implements HTableInterface, RegionLocator { return operationTimeout; } + @Override public void setRpcTimeout(int rpcTimeout) { + this.rpcTimeout = rpcTimeout; + } + + @Override public int getRpcTimeout() { + return rpcTimeout; + } + @Override public String toString() { return tableName + ";" + connection; diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java index 4b998a6..d837bf8 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java @@ -672,5 +672,21 @@ public class HTablePool implements Closeable { checkState(); return table.checkAndMutate(row, family, qualifier, compareOp, value, mutation); } + + @Override public void setOperationTimeout(int operationTimeout) { + table.setOperationTimeout(operationTimeout); + } + + @Override public int getOperationTimeout() { + return table.getOperationTimeout(); + } + + @Override public void setRpcTimeout(int rpcTimeout) { + table.setRpcTimeout(rpcTimeout); + } + + @Override public int getRpcTimeout() { + return table.getRpcTimeout(); + } } } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCaller.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCaller.java index 896222c..1d14f71 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCaller.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCaller.java @@ -63,21 +63,23 @@ public class RpcRetryingCaller { private final long pause; private final int retries; + private final int rpcTimeout;// timeout for each rpc request private final AtomicBoolean cancelled = new AtomicBoolean(false); private final RetryingCallerInterceptor interceptor; private final RetryingCallerInterceptorContext context; public RpcRetryingCaller(long pause, int retries, int startLogErrorsCnt) { - this(pause, retries, RetryingCallerInterceptorFactory.NO_OP_INTERCEPTOR, startLogErrorsCnt); + this(pause, retries, RetryingCallerInterceptorFactory.NO_OP_INTERCEPTOR, startLogErrorsCnt, 0); } public RpcRetryingCaller(long pause, int retries, - RetryingCallerInterceptor interceptor, int startLogErrorsCnt) { + RetryingCallerInterceptor interceptor, int startLogErrorsCnt, int rpcTimeout) { this.pause = pause; this.retries = retries; this.interceptor = interceptor; context = interceptor.createEmptyContext(); this.startLogErrorsCnt = startLogErrorsCnt; + this.rpcTimeout = rpcTimeout; } private int getRemainingTime(int callTimeout) { @@ -97,6 +99,14 @@ public class RpcRetryingCaller { } } + private int getTimeout(int callTimeout){ + int timeout = getRemainingTime(callTimeout); + if (timeout <= 0 || rpcTimeout > 0 && rpcTimeout < timeout){ + timeout = rpcTimeout; + } + return timeout; + } + public void cancel(){ synchronized (cancelled){ cancelled.set(true); @@ -123,7 +133,7 @@ public class RpcRetryingCaller { try { callable.prepare(tries != 0); // if called with false, check table status on ZK interceptor.intercept(context.prepare(callable, tries)); - return callable.call(getRemainingTime(callTimeout)); + return callable.call(getTimeout(callTimeout)); } catch (PreemptiveFastFailException e) { throw e; } catch (Throwable t) { diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerFactory.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerFactory.java index 1bf7bb0..09b70b8 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerFactory.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RpcRetryingCallerFactory.java @@ -33,6 +33,7 @@ public class RpcRetryingCallerFactory { protected final Configuration conf; private final long pause; private final int retries; + private final int rpcTimeout; private final RetryingCallerInterceptor interceptor; private final int startLogErrorsCnt; private final boolean enableBackPressure; @@ -53,6 +54,7 @@ public class RpcRetryingCallerFactory { this.interceptor = interceptor; enableBackPressure = conf.getBoolean(HConstants.ENABLE_CLIENT_BACKPRESSURE, HConstants.DEFAULT_ENABLE_CLIENT_BACKPRESSURE); + rpcTimeout = conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY,HConstants.DEFAULT_HBASE_RPC_TIMEOUT); } /** @@ -62,11 +64,32 @@ public class RpcRetryingCallerFactory { this.stats = statisticTracker; } + /** + * Create a new RetryingCaller with specific rpc timeout. + */ + public RpcRetryingCaller newCaller(int rpcTimeout) { + // We store the values in the factory instance. This way, constructing new objects + // is cheap as it does not require parsing a complex structure. + RpcRetryingCaller caller = new RpcRetryingCaller(pause, retries, interceptor, + startLogErrorsCnt, rpcTimeout); + + // wrap it with stats, if we are tracking them + if (enableBackPressure && this.stats != null) { + caller = new StatsTrackingRpcRetryingCaller(pause, retries, interceptor, + startLogErrorsCnt, stats); + } + + return caller; + } + + /** + * Create a new RetryingCaller with configured rpc timeout. + */ public RpcRetryingCaller newCaller() { // We store the values in the factory instance. This way, constructing new objects // is cheap as it does not require parsing a complex structure. RpcRetryingCaller caller = new RpcRetryingCaller(pause, retries, interceptor, - startLogErrorsCnt); + startLogErrorsCnt, rpcTimeout); // wrap it with stats, if we are tracking them if (enableBackPressure && this.stats != null) { diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/StatsTrackingRpcRetryingCaller.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/StatsTrackingRpcRetryingCaller.java index fc175bb..cbd625d 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/StatsTrackingRpcRetryingCaller.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/StatsTrackingRpcRetryingCaller.java @@ -39,7 +39,7 @@ public class StatsTrackingRpcRetryingCaller extends RpcRetryingCaller { public StatsTrackingRpcRetryingCaller(long pause, int retries, RetryingCallerInterceptor interceptor, int startLogErrorsCnt, ServerStatisticTracker stats) { - super(pause, retries, interceptor, startLogErrorsCnt); + super(pause, retries, interceptor, startLogErrorsCnt, 0); this.stats = stats; } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Table.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Table.java index 9a6744b..8c6169d 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Table.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Table.java @@ -595,4 +595,35 @@ public interface Table extends Closeable { */ boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, byte[] value, RowMutations mutation) throws IOException; + + /** + * Set timeout (millisecond) of each operation in this Table instance, will override the value + * of hbase.client.operation.timeout in configuration. + * Operation timeout is a top-level restriction that makes sure a blocking method will not be + * blocked more than this. In each operation, if rpc request fails because of timeout or + * other reason, it will retry until success or throw a RetriesExhaustedException. But if the + * total time being blocking reach the operation timeout before retries exhausted, it will break + * early and throw SocketTimeoutException. + * @param operationTimeout the total timeout of each operation in millisecond. + */ + public void setOperationTimeout(int operationTimeout); + + /** + * Get timeout (millisecond) of each operation for in Table instance. + */ + public int getOperationTimeout(); + + /** + * Set timeout (millisecond) of each rpc request in operations of this Table instance, will + * override the value of hbase.rpc.timeout in configuration. + * If a rpc request waiting too long, it will stop waiting and send a new request to retry until + * retries exhausted or operation timeout reached. + * @param rpcTimeout the timeout of each rpc request in millisecond. + */ + public void setRpcTimeout(int rpcTimeout); + + /** + * Get timeout (millisecond) of each rpc request in this Table instance. + */ + public int getRpcTimeout(); } diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestFastFailWithoutTestUtil.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestFastFailWithoutTestUtil.java index 7cb0be6..b387683 100644 --- a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestFastFailWithoutTestUtil.java +++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestFastFailWithoutTestUtil.java @@ -563,7 +563,7 @@ public class TestFastFailWithoutTestUtil { public RpcRetryingCaller getRpcRetryingCaller(int pauseTime, int retries, RetryingCallerInterceptor interceptor) { - return new RpcRetryingCaller(pauseTime, retries, interceptor, 9) { + return new RpcRetryingCaller(pauseTime, retries, interceptor, 9, 0) { @Override public Void callWithRetries(RetryingCallable callable, int callTimeout) throws IOException, RuntimeException { diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java index ccf6db6..7985083 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java @@ -272,10 +272,10 @@ public final class HConstants { /** Parameter name for HBase client IPC pool size */ public static final String HBASE_CLIENT_IPC_POOL_SIZE = "hbase.client.ipc.pool.size"; - /** Parameter name for HBase client operation timeout, which overrides RPC timeout */ + /** Parameter name for HBase client operation timeout. */ public static final String HBASE_CLIENT_OPERATION_TIMEOUT = "hbase.client.operation.timeout"; - /** Parameter name for HBase client operation timeout, which overrides RPC timeout */ + /** Parameter name for HBase client operation timeout. */ public static final String HBASE_CLIENT_META_OPERATION_TIMEOUT = "hbase.client.meta.operation.timeout"; diff --git a/hbase-common/src/main/resources/hbase-default.xml b/hbase-common/src/main/resources/hbase-default.xml index 80fe1a8..97bff7e 100644 --- a/hbase-common/src/main/resources/hbase-default.xml +++ b/hbase-common/src/main/resources/hbase-default.xml @@ -847,11 +847,20 @@ possible configurations would overwhelm and obscure the important. hbase.rpc.timeout 60000 - This is for the RPC layer to define how long HBase client applications + This is for the RPC layer to define how long (millisecond) HBase client applications take for a remote call to time out. It uses pings to check connections but will eventually throw a TimeoutException. + hbase.client.operation.timeout + 1200000 + Operation timeout is a top-level restriction (millisecond) that makes sure a + blocking operation in Table will not be blocked more than this. In each operation, if rpc + request fails because of timeout or other reason, it will retry until success or throw + RetriesExhaustedException. But if the total time being blocking reach the operation timeout + before retries exhausted, it will break early and throw SocketTimeoutException. + + hbase.cells.scanned.per.heartbeat.check 10000 The number of cells scanned in between heartbeat checks. Heartbeat diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java index b6ed330..8fa1b8a 100644 --- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java +++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java @@ -857,4 +857,20 @@ public class RemoteHTable implements Table { CompareOp compareOp, byte[] value, RowMutations rm) throws IOException { throw new UnsupportedOperationException("checkAndMutate not implemented"); } + + @Override public void setOperationTimeout(int operationTimeout) { + throw new UnsupportedOperationException(); + } + + @Override public int getOperationTimeout() { + throw new UnsupportedOperationException(); + } + + @Override public void setRpcTimeout(int rpcTimeout) { + throw new UnsupportedOperationException(); + } + + @Override public int getRpcTimeout() { + throw new UnsupportedOperationException(); + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/HTableWrapper.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/HTableWrapper.java index 1f84bb4..2d25f63 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/HTableWrapper.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/HTableWrapper.java @@ -365,4 +365,20 @@ public class HTableWrapper implements HTableInterface { CompareOp compareOp, byte[] value, RowMutations rm) throws IOException { return table.checkAndMutate(row, family, qualifier, compareOp, value, rm); } + + @Override public void setOperationTimeout(int operationTimeout) { + table.setOperationTimeout(operationTimeout); + } + + @Override public int getOperationTimeout() { + return table.getOperationTimeout(); + } + + @Override public void setRpcTimeout(int rpcTimeout) { + table.setRpcTimeout(rpcTimeout); + } + + @Override public int getRpcTimeout() { + return table.getRpcTimeout(); + } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java index 233e36b..501d836 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java @@ -126,9 +126,19 @@ public class TestHCM { } } + public static class SleepCoprocessor extends BaseRegionObserver { + public static final int SLEEP_TIME = 5000; + + @Override public void preGetOp(final ObserverContext e, + final Get get, final List results) throws IOException { + Threads.sleep(SLEEP_TIME); + } + } + @BeforeClass public static void setUpBeforeClass() throws Exception { TEST_UTIL.getConfiguration().setBoolean(HConstants.STATUS_PUBLISHED, true); + TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 5); TEST_UTIL.startMiniCluster(2); } @@ -299,7 +309,7 @@ public class TestHCM { HTableDescriptor hdt = TEST_UTIL.createTableDescriptor("HCM-testOperationTimeout"); hdt.addCoprocessor(SleepAndFailFirstTime.class.getName()); HTable table = TEST_UTIL.createTable(hdt, new byte[][]{FAM_NAM}, TEST_UTIL.getConfiguration()); - + table.setRpcTimeout(Integer.MAX_VALUE); // Check that it works if the timeout is big enough table.setOperationTimeout(120 * 1000); table.get(new Get(FAM_NAM)); @@ -322,6 +332,20 @@ public class TestHCM { } } + @Test(expected = RetriesExhaustedException.class) + public void testRpcTimeout() throws Exception { + HTableDescriptor hdt = TEST_UTIL.createTableDescriptor("HCM-testRpcTimeout"); + hdt.addCoprocessor(SleepCoprocessor.class.getName()); + Configuration c = new Configuration(TEST_UTIL.getConfiguration()); + + try (Table t = TEST_UTIL.createTable(hdt, new byte[][] { FAM_NAM }, c)) { + assert t instanceof HTable; + HTable table = (HTable) t; + table.setRpcTimeout(SleepCoprocessor.SLEEP_TIME / 2); + table.setOperationTimeout(SleepCoprocessor.SLEEP_TIME * 100); + table.get(new Get(FAM_NAM)); + } + } private void testConnectionClose(boolean allowsInterrupt) throws Exception { TableName tableName = TableName.valueOf("HCM-testConnectionClose" + allowsInterrupt); -- 2.6.4 (Apple Git-63)