@Override
    public ClientProtos.ScanResponse scan(final RpcController controller,
      final ClientProtos.ScanRequest request) throws ServiceException {

      String regionName = Bytes.toString(request.getRegion().getValue().toByteArray());
      if (regionName.contains(TABLE_NAME.getNameAsString())) {

        // if the client's timeout is exceeded, it may either retry or attempt to close
        // the scanner. we don't want to allow either until we've verified the server handling.
        // so only allow 1 request at a time to our test table
        try {
          if (!lock.tryLock(60, TimeUnit.SECONDS)) {
            throw new ServiceException("Failed to get lock");
          }
        } catch (InterruptedException e) {
          throw new ServiceException(e);
        }

        try {
          LOG.info("SLEEPING");
          Thread.sleep(TIMEOUT * 2);
        } catch (Exception e) {
        }

        try {
          return super.scan(controller, request);
        } catch (ServiceException e) {
          if (
            e.getCause() instanceof ScannerResetException
              && e.getCause().getCause() instanceof TimeoutIOException
          ) {
            LOG.info("caught EXPECTED exception in scan after sleep", e);
            caughtTimeoutException = true;
          } else {
            LOG.warn("caught UNEXPECTED exception in scan after sleep", e);
          }
        } finally {
          scannerCount = getScannersCount();
          lock.unlock();
        }
      }

      return super.scan(controller, request);

    }
If a client's timeout would be exceeded before scan results are ready, there is no point
returning results to the client. Worse, for openScanner calls, the client cannot close the
timed out scanner so this leaks scanners on the server. This test verifies that we properly
track and cleanup scanners when a client timeout is exceeded. This should be more rare when
heartbeats are enabled, since we try to return before timeout there. But it's still possible if
queueing eats up most of the timeout or the inner workings of the scan were slowed down enough
to still exceed the timeout despite the calculated heartbeat deadline.
hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScannerTimeoutHandling.java