private static void ensureThatExceptionHandlerIsLast(ChannelPipeline pipeline) { ChannelInboundHandler exceptionHandler = ChannelExceptionHandler.getInstance(); if (pipeline.last() != exceptionHandler || pipeline.context(exceptionHandler) == null) { return; } pipeline.remove(exceptionHandler); pipeline.addLast(exceptionHandler); }
/** * Creates an instance of {@link NettyPacketReader}. If this is used to read a block remotely, it * requires the block to be locked beforehand and the lock ID is passed to this class. * * @param context the file system context * @param address the netty data server network address * @param id the block ID or UFS file ID * @param offset the offset * @param len the length to read * @param lockId the lock ID * @param sessionId the session ID * @param type the request type (block or UFS file) * @throws IOException if it fails to acquire a netty channel */ private NettyPacketReader( FileSystemContext context, InetSocketAddress address, long id, long offset, long len, long lockId, long sessionId, Protocol.RequestType type) throws IOException { Preconditions.checkArgument(offset >= 0 && len > 0); mContext = context; mAddress = address; mId = id; mStart = offset; mPosToRead = offset; mBytesToRead = len; mRequestType = type; mChannel = context.acquireNettyChannel(address); ChannelPipeline pipeline = mChannel.pipeline(); if (!(pipeline.last() instanceof RPCMessageDecoder)) { throw new RuntimeException( String.format( "Channel pipeline has unexpected handlers %s.", pipeline.last().getClass().getCanonicalName())); } mChannel.pipeline().addLast(new PacketReadHandler()); Protocol.ReadRequest readRequest = Protocol.ReadRequest.newBuilder() .setId(id) .setOffset(offset) .setLength(len) .setLockId(lockId) .setSessionId(sessionId) .setType(type) .build(); mChannel .writeAndFlush(new RPCProtoMessage(readRequest)) .addListener(ChannelFutureListener.CLOSE_ON_FAILURE); }