示例#1
0
 /**
  * Returns the appropriate {@link DataBuffer} representing the data to send, depending on the
  * configurable transfer type.
  *
  * @param req The initiating {@link RPCBlockReadRequest}
  * @param reader The {@link BlockReader} for the block to read
  * @param readLength The length, in bytes, of the data to read from the block
  * @return a {@link DataBuffer} representing the data
  * @throws IOException
  * @throws IllegalArgumentException
  */
 private DataBuffer getDataBuffer(RPCBlockReadRequest req, BlockReader reader, long readLength)
     throws IOException, IllegalArgumentException {
   switch (mTransferType) {
     case MAPPED:
       ByteBuffer data = reader.read(req.getOffset(), (int) readLength);
       return new DataByteBuffer(data, readLength);
     case TRANSFER: // intend to fall through as TRANSFER is the default type.
     default:
       if (reader.getChannel() instanceof FileChannel) {
         return new DataFileChannel(
             (FileChannel) reader.getChannel(), req.getOffset(), readLength);
       }
       reader.close();
       throw new IllegalArgumentException("Only FileChannel is supported!");
   }
 }
示例#2
0
 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);
 }
示例#3
0
  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();
      }
    }
  }