private void validateBounds(final RPCBlockReadRequest req, final long fileLength) {
   Preconditions.checkArgument(
       req.getOffset() <= fileLength,
       "Offset(%s) is larger than file length(%s)",
       req.getOffset(),
       fileLength);
   Preconditions.checkArgument(
       req.getLength() == -1 || req.getOffset() + req.getLength() <= fileLength,
       "Offset(%s) plus length(%s) is larger than file length(%s)",
       req.getOffset(),
       req.getLength(),
       fileLength);
 }
  private void handleBlockReadRequest(
      final ChannelHandlerContext ctx, final RPCBlockReadRequest req) throws IOException {
    final long blockId = req.getBlockId();
    final long offset = req.getOffset();
    final long len = req.getLength();
    final long lockId = req.getLockId();
    final long sessionId = req.getSessionId();

    BlockReader reader;
    try {
      reader = mBlockWorker.readBlockRemote(sessionId, blockId, lockId);
    } catch (BlockDoesNotExistException e) {
      throw new IOException(e);
    } catch (InvalidWorkerStateException e) {
      throw new IOException(e);
    }
    try {
      req.validate();
      final long fileLength = reader.getLength();
      validateBounds(req, fileLength);
      final long readLength = returnLength(offset, len, fileLength);
      RPCBlockReadResponse resp =
          new RPCBlockReadResponse(
              blockId,
              offset,
              readLength,
              getDataBuffer(req, reader, readLength),
              RPCResponse.Status.SUCCESS);
      ChannelFuture future = ctx.writeAndFlush(resp);
      future.addListener(ChannelFutureListener.CLOSE);
      future.addListener(new ClosableResourceChannelListener(reader));
      mBlockWorker.accessBlock(sessionId, blockId);
      LOG.info("Preparation for responding to remote block request for: {} done.", blockId);
    } catch (Exception e) {
      LOG.error("The file is not here : {}", e.getMessage(), e);
      RPCBlockReadResponse resp =
          RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.FILE_DNE);
      ChannelFuture future = ctx.writeAndFlush(resp);
      future.addListener(ChannelFutureListener.CLOSE);
      if (reader != null) {
        reader.close();
      }
    }
  }