private void terminateResumerIfPossible() {
    if (resumer == null) {
      return;
    }
    // AsyncTableResultScanner.close means we do not need scan results any more, but for
    // ScanResumerImpl.resume, it would perform another scan on RegionServer and call
    // AsyncTableResultScanner.onNext again when ScanResponse is received. This time
    // AsyncTableResultScanner.onNext would do nothing else but just discard ScanResponse
    // because AsyncTableResultScanner.closed is true. So here we would better save this
    // unnecessary scan on RegionServer and introduce ScanResumerImpl.terminate to close
    // scanner directly.
    if (resumer instanceof ScanResumerImpl) {
      ((ScanResumerImpl) resumer).terminate();
    } else {
      resumePrefetch();
    }
    resumer = null;
  }
The {@link ResultScanner} implementation for {@link RawAsyncTableImpl}. It will fetch data
automatically in background and cache it in memory. Typically, the {@link #maxCacheSize} will be
{@code 2 * scan.getMaxResultSize()}.
hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncTableResultScanner.java