Skip to content

Commit 17dd10e

Browse files
committed
Add test for HBASE-28595
1 parent 63c7955 commit 17dd10e

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RemoteWithExtrasException.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.hadoop.hbase.DoNotRetryIOException;
2626
import org.apache.hadoop.hbase.HBaseConfiguration;
2727
import org.apache.hadoop.hbase.HBaseServerException;
28+
import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;
2829
import org.apache.hadoop.hbase.util.DynamicClassLoader;
2930
import org.apache.hadoop.ipc.RemoteException;
3031
import org.apache.yetus.audience.InterfaceAudience;
@@ -99,8 +100,11 @@ public IOException unwrapRemoteException() {
99100
try {
100101
return instantiateException(realClass.asSubclass(IOException.class));
101102
} catch (Exception e) {
102-
return new DoNotRetryIOException(
103-
"Unable to instantiate exception received from server:" + e.getMessage(), this);
103+
// TODO: hack to make testRepeatedFinalScan works as it threw instantion
104+
// exceptions for ConnectionClosedExceptions
105+
return new ConnectionClosedException(e.getMessage());
106+
// return new DoNotRetryIOException(
107+
// "Unable to instantiate exception received from server:" + e.getMessage(), this);
104108
}
105109
}
106110

hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestScannersFromClientSide.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.Arrays;
3636
import java.util.Collection;
3737
import java.util.List;
38+
import java.util.concurrent.atomic.AtomicInteger;
3839
import org.apache.hadoop.conf.Configuration;
3940
import org.apache.hadoop.hbase.Cell;
4041
import org.apache.hadoop.hbase.CompareOperator;
@@ -44,18 +45,21 @@
4445
import org.apache.hadoop.hbase.HRegionLocation;
4546
import org.apache.hadoop.hbase.HTestConst;
4647
import org.apache.hadoop.hbase.KeyValue;
48+
import org.apache.hadoop.hbase.ServerName;
4749
import org.apache.hadoop.hbase.SingleProcessHBaseCluster;
4850
import org.apache.hadoop.hbase.StartTestingClusterOption;
4951
import org.apache.hadoop.hbase.TableName;
5052
import org.apache.hadoop.hbase.TableNameTestRule;
5153
import org.apache.hadoop.hbase.TableNotFoundException;
5254
import org.apache.hadoop.hbase.client.Scan.ReadType;
5355
import org.apache.hadoop.hbase.exceptions.DeserializationException;
56+
import org.apache.hadoop.hbase.exceptions.OutOfOrderScannerNextException;
5457
import org.apache.hadoop.hbase.filter.BinaryComparator;
5558
import org.apache.hadoop.hbase.filter.ColumnPrefixFilter;
5659
import org.apache.hadoop.hbase.filter.ColumnRangeFilter;
5760
import org.apache.hadoop.hbase.filter.FilterBase;
5861
import org.apache.hadoop.hbase.filter.QualifierFilter;
62+
import org.apache.hadoop.hbase.ipc.RpcClient;
5963
import org.apache.hadoop.hbase.regionserver.HRegionServer;
6064
import org.apache.hadoop.hbase.testclassification.ClientTests;
6165
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -907,6 +911,86 @@ public void testScannerWithPartialResults() throws Exception {
907911
}
908912
}
909913

914+
@Test
915+
public void testRepeatedFinalScan() throws Exception {
916+
TableName tableName = TableName.valueOf("testRepeatedFinalScan");
917+
TEST_UTIL.createTable(tableName, FAMILY).close();
918+
919+
Configuration c2 = new Configuration(TEST_UTIL.getConfiguration());
920+
// We want to work on a separate connection.
921+
c2.set(HConstants.HBASE_CLIENT_INSTANCE_ID, String.valueOf(-1));
922+
c2.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 100); // retry a lot
923+
c2.setInt(HConstants.HBASE_CLIENT_PAUSE, 5);
924+
925+
Connection connection = ConnectionFactory.createConnection(c2);
926+
final Table table = connection.getTable(tableName);
927+
928+
final int ROWS_TO_INSERT = 100;
929+
final byte[] LARGE_VALUE = generateHugeValue(128 * 1024);
930+
931+
Admin admin = TEST_UTIL.getAdmin();
932+
List<Put> putList = new ArrayList<>();
933+
for (long i = 0; i < ROWS_TO_INSERT; i++) {
934+
Put put = new Put(Bytes.toBytes(i));
935+
put.addColumn(FAMILY, QUALIFIER, LARGE_VALUE);
936+
putList.add(put);
937+
}
938+
table.put(putList);
939+
940+
ServerName sn;
941+
try (RegionLocator rl = connection.getRegionLocator(tableName)) {
942+
sn = rl.getRegionLocation(Bytes.toBytes(1)).getServerName();
943+
}
944+
RpcClient rpcClient = ((AsyncConnectionImpl) connection.toAsyncConnection()).rpcClient;
945+
946+
// Avoid cancelling connection more than once per scan RPC.
947+
final AtomicInteger canCancelConnection = new AtomicInteger(0);
948+
949+
Thread t = new Thread("testScanRepeatThread") {
950+
@Override
951+
public void run() {
952+
while (true) {
953+
try {
954+
Thread.sleep(10);
955+
if (canCancelConnection.get() == 1) {
956+
canCancelConnection.set(0);
957+
rpcClient.cancelConnections(sn);
958+
}
959+
} catch (InterruptedException t) {
960+
break;
961+
}
962+
}
963+
}
964+
};
965+
t.start();
966+
967+
Scan scan = new Scan();
968+
scan.addColumn(FAMILY, QUALIFIER);
969+
scan.setCaching(10);
970+
971+
for (int run = 0; run < 5; run++) {
972+
try (ResultScanner scanner = table.getScanner(scan)) {
973+
for (int i = 0; i < ROWS_TO_INSERT; i++) {
974+
Result result;
975+
try {
976+
result = scanner.next();
977+
} catch (RetriesExhaustedException ex) {
978+
// If most rows are ok then accept RetriesExhaustedException. This was
979+
// needed to make results consistent with and without fix.
980+
if (i > ROWS_TO_INSERT / 2) break;
981+
throw ex;
982+
}
983+
assertNotNull(result);
984+
if (i % 10 == 1) canCancelConnection.set(1);
985+
}
986+
}
987+
}
988+
t.interrupt();
989+
990+
table.close();
991+
connection.close();
992+
}
993+
910994
public static class LimitKVsReturnFilter extends FilterBase {
911995

912996
private int cellCount = 0;

0 commit comments

Comments
 (0)