private void handleBlockRequest(final ChannelHandlerContext ctx, final RPCBlockRequest req) throws IOException { final long blockId = req.getBlockId(); final long offset = req.getOffset(); final long len = req.getLength(); long lockId; try { // zd add logInfo LOG.info("Preparation for responding to remote block request for: " + blockId); lockId = mDataManager.lockBlock(Users.DATASERVER_USER_ID, blockId); } catch (IOException ioe) { LOG.error("Failed to lock block: " + blockId, ioe); RPCBlockResponse resp = RPCBlockResponse.createErrorResponse(req, RPCResponse.Status.BLOCK_LOCK_ERROR); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); return; } BlockReader reader = mDataManager.readBlockRemote(Users.DATASERVER_USER_ID, blockId, lockId); try { req.validate(); final long fileLength = reader.getLength(); validateBounds(req, fileLength); final long readLength = returnLength(offset, len, fileLength); RPCBlockResponse resp = new RPCBlockResponse( blockId, offset, readLength, getDataBuffer(req, reader, readLength), RPCResponse.Status.SUCCESS); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); future.addListener(new ClosableResourceChannelListener(reader)); mDataManager.accessBlock(Users.DATASERVER_USER_ID, blockId); LOG.info("Preparation for responding to remote block request for: " + blockId + " done."); } catch (Exception e) { LOG.error("The file is not here : " + e.getMessage(), e); RPCBlockResponse resp = RPCBlockResponse.createErrorResponse(req, RPCResponse.Status.FILE_DNE); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); if (reader != null) { reader.close(); } } finally { mDataManager.unlockBlock(lockId); } }
/** * 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!"); } }
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(); } } }