protected ChunkingChannelBuffer newChunkingBuffer( ChannelBuffer bufferToWriteTo, Channel channel, int capacity, byte internalProtocolVersion, byte applicationProtocolVersion ) { return new ChunkingChannelBuffer( bufferToWriteTo, channel, capacity, internalProtocolVersion, applicationProtocolVersion ); }
private void sendChunkIfNeeded( int bytesPlus ) { // Note: This is wasteful, it should pack as much data as possible into the current chunk before sending it off. // Refactor when there is time. if ( writerIndex() + bytesPlus >= capacity ) { setContinuation( CONTINUATION_MORE ); writeCurrentChunk(); buffer = newChannelBuffer(); addRoomForContinuationHeader(); } }
@Override public void clear() { clear( false ); }
public void done() { if ( readable() /* Meaning that something has been written to it and can be read/sent */ ) { writeCurrentChunk(); } }
private void addRoomForContinuationHeader() { continuationPosition = writerIndex(); // byte 0: [pppp,ppoc] p: internal protocol version, o: outcome, c: continuation // byte 1: [aaaa,aaaa] a: application protocol version buffer.writeBytes( header( CONTINUATION_LAST ) ); }
@Override public void writeByte( int value ) { sendChunkIfNeeded( 1 ); buffer.writeByte( value ); }
public void serializeRequest( Channel channel, ChannelBuffer buffer, RequestType type, RequestContext ctx, Serializer payload ) throws IOException { buffer.clear(); ChunkingChannelBuffer chunkingBuffer = new ChunkingChannelBuffer( buffer, channel, chunkSize, internalProtocolVersion, applicationProtocolVersion ); chunkingBuffer.writeByte( type.id() ); writeContext( ctx, chunkingBuffer ); payload.write( chunkingBuffer ); chunkingBuffer.done(); }
protected void writeFailureResponse( Throwable exception, ChunkingChannelBuffer buffer ) { try { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream( bytes ); out.writeObject( exception ); out.close(); buffer.writeBytes( bytes.toByteArray() ); buffer.done(); } catch ( IOException e ) { msgLog.warn( "Couldn't send cause of error to client", exception ); } }
private void writeCurrentChunk() { if ( !channel.isOpen() || !channel.isConnected() || !channel.isBound() ) { throw new ComException( "Channel has been closed, so no need to try to write to it anymore. Client closed it?" ); } waitForClientToCatchUpOnReadingChunks(); ChannelFuture future = channel.write( buffer ); future.addListener( newChannelFutureListener( buffer ) ); writeAheadCounter.incrementAndGet(); }
public ChunkingChannelBuffer( ChannelBuffer buffer, Channel channel, int capacity, byte internalProtocolVersion, byte applicationProtocolVersion ) { this.buffer = buffer; this.channel = channel; this.capacity = capacity; this.internalProtocolVersion = internalProtocolVersion; this.applicationProtocolVersion = applicationProtocolVersion; addRoomForContinuationHeader(); }
@Override protected ChannelFutureListener newChannelFutureListener( final ChannelBuffer buffer ) { return future -> { buffer.clear(); freeBuffers.offer( buffer ); BufferReusingChunkingChannelBuffer.super.operationComplete( future ); }; } }
private void setContinuation( byte continuation ) { buffer.setBytes( continuationPosition, header( continuation ) ); }
@Override public void writeLong( long value ) { sendChunkIfNeeded( 8 ); buffer.writeLong( value ); }
public void clear( boolean failure ) { buffer.clear(); this.failure = failure; addRoomForContinuationHeader(); }
@Override public void writeShort( int value ) { sendChunkIfNeeded( 2 ); buffer.writeShort( value ); }
@Override public void messageReceived( ChannelHandlerContext ctx, MessageEvent event ) { try { ChannelBuffer message = (ChannelBuffer) event.getMessage(); handleRequest( message, event.getChannel() ); } catch ( Throwable e ) { msgLog.error( "Error handling request", e ); // Attempt to reply to the client ChunkingChannelBuffer buffer = newChunkingBuffer( event.getChannel() ); buffer.clear( /* failure = */true ); writeFailureResponse( e, buffer ); ctx.getChannel().close(); tryToCloseChannel( ctx.getChannel() ); throw e; } }
@Override public void writeDouble( double value ) { sendChunkIfNeeded( 8 ); buffer.writeDouble( value ); }
@Override public void writeBytes( ChannelBuffer src, int srcIndex, int length ) { sendChunkIfNeeded( length ); buffer.writeBytes( src, srcIndex, length ); }
@Override public void writeBytes( ByteBuffer src ) { sendChunkIfNeeded( src.limit() ); buffer.writeBytes( src ); }
@Override public void writeBytes( byte[] src ) { sendChunkIfNeeded( src.length ); buffer.writeBytes( src ); }