You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by wc...@apache.org on 2019/11/01 10:55:13 UTC

[hbase] branch branch-2.2 updated: HBASE-23238 Additional test and checks for null references on ScannerCallableWithReplicas (#780)

This is an automated email from the ASF dual-hosted git repository.

wchevreuil pushed a commit to branch branch-2.2
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2.2 by this push:
     new ab8a2ab  HBASE-23238 Additional test and checks for null references on ScannerCallableWithReplicas (#780)
ab8a2ab is described below

commit ab8a2abbc6e88a8391acc1a1bf8c3d58436f8221
Author: Wellington Chevreuil <wc...@apache.org>
AuthorDate: Fri Nov 1 10:28:55 2019 +0000

    HBASE-23238 Additional test and checks for null references on ScannerCallableWithReplicas (#780)
    
    Signed-off-by: Sean Busbey <bu...@apache.org>
    (cherry picked from commit 577db5d7e50c56b4773c9ce92b807aae80bf5706)
---
 .../hbase/client/ScannerCallableWithReplicas.java  | 11 ++-
 .../hbase/client/TestScannersFromClientSide.java   | 80 +++++++++++++++++++++-
 2 files changed, 87 insertions(+), 4 deletions(-)

diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
index bcb81f7..5fcc440 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
@@ -94,7 +94,12 @@ class ScannerCallableWithReplicas implements RetryingCallable<Result[]> {
   }
 
   public void setClose() {
-    currentScannerCallable.setClose();
+    if(currentScannerCallable != null) {
+      currentScannerCallable.setClose();
+    } else {
+      LOG.warn("Calling close on ScannerCallable reference that is already null, "
+        + "which shouldn't happen.");
+    }
   }
 
   public void setRenew(boolean val) {
@@ -136,6 +141,10 @@ class ScannerCallableWithReplicas implements RetryingCallable<Result[]> {
       Result[] r = currentScannerCallable.call(timeout);
       currentScannerCallable = null;
       return r;
+    } else if(currentScannerCallable == null) {
+      LOG.warn("Another call received, but our ScannerCallable is already null. "
+        + "This shouldn't happen, but there's not much to do, so logging and returning null.");
+      return null;
     }
     // We need to do the following:
     //1. When a scan goes out to a certain replica (default or not), we need to
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestScannersFromClientSide.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestScannersFromClientSide.java
index af02482..579db5c 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestScannersFromClientSide.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestScannersFromClientSide.java
@@ -46,6 +46,9 @@ import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.HTestConst;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.MiniHBaseCluster;
+import org.apache.hadoop.hbase.exceptions.DeserializationException;
+import org.apache.hadoop.hbase.filter.FilterBase;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.TableNotFoundException;
 import org.apache.hadoop.hbase.filter.BinaryComparator;
@@ -54,7 +57,6 @@ import org.apache.hadoop.hbase.filter.ColumnRangeFilter;
 import org.apache.hadoop.hbase.filter.QualifierFilter;
 import org.apache.hadoop.hbase.regionserver.HRegionServer;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
-import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.junit.After;
@@ -945,7 +947,7 @@ public class TestScannersFromClientSide {
     final byte[] LARGE_VALUE = generateHugeValue(128 * 1024);
 
     try (Table table = TEST_UTIL.createTable(tableName, FAMILY);
-        Admin admin = TEST_UTIL.getAdmin()) {
+      Admin admin = TEST_UTIL.getAdmin()) {
       List<Put> putList = new ArrayList<>();
       for (long i = 0; i < ROWS_TO_INSERT; i++) {
         Put put = new Put(Bytes.toBytes(i));
@@ -975,7 +977,79 @@ public class TestScannersFromClientSide {
         }
       }
       assertEquals("Expected " + ROWS_TO_INSERT + " rows in the table but it is " + count,
-          ROWS_TO_INSERT, count);
+        ROWS_TO_INSERT, count);
     }
   }
+
+  @Test
+  public void testScannerWithPartialResults() throws Exception {
+    TableName tableName = TableName.valueOf("testScannerWithPartialResults");
+    try (Table table = TEST_UTIL.createMultiRegionTable(tableName,
+      Bytes.toBytes("c"), 4)) {
+      List<Put> puts = new ArrayList<>();
+      byte[] largeArray = new byte[10000];
+      Put put = new Put(Bytes.toBytes("aaaa0"));
+      put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("1"), Bytes.toBytes("1"));
+      put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("2"), Bytes.toBytes("2"));
+      put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("3"), Bytes.toBytes("3"));
+      put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("4"), Bytes.toBytes("4"));
+      puts.add(put);
+      put = new Put(Bytes.toBytes("aaaa1"));
+      put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("1"), Bytes.toBytes("1"));
+      put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("2"), largeArray);
+      put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("3"), largeArray);
+      puts.add(put);
+      table.put(puts);
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("c"));
+      scan.setAttribute(Scan.SCAN_ATTRIBUTES_TABLE_NAME, tableName.getName());
+      scan.setMaxResultSize(10001);
+      scan.setStopRow(Bytes.toBytes("bbbb"));
+      scan.setFilter(new LimitKVsReturnFilter());
+      ResultScanner rs = table.getScanner(scan);
+      Result result;
+      int expectedKvNumber = 6;
+      int returnedKvNumber = 0;
+      while((result = rs.next()) != null){
+        returnedKvNumber += result.listCells().size();
+      }
+      rs.close();
+      assertEquals(expectedKvNumber, returnedKvNumber);
+    }
+  }
+
+  public static class LimitKVsReturnFilter extends FilterBase {
+
+    private static int total = 0;
+
+    @Override
+    public ReturnCode filterCell(Cell v) throws IOException {
+      if(total>=6) {
+        total++;
+        return ReturnCode.SKIP;
+      }
+      total++;
+      return ReturnCode.INCLUDE;
+    }
+
+    @Override
+    public boolean filterAllRemaining() throws IOException {
+      if(total<7) {
+        return false;
+      }
+      total++;
+      return true;
+    }
+
+    @Override
+    public String toString() {
+      return this.getClass().getSimpleName();
+    }
+
+    public static LimitKVsReturnFilter parseFrom(final byte [] pbBytes)
+      throws DeserializationException {
+      return new LimitKVsReturnFilter();
+    }
+  }
+
 }