private void processReply(IStream stream, SynReplyFrame frame) { stream.process(frame); if (stream.isClosed()) removeStream(stream); }
private void processHeaders(IStream stream, HeadersFrame frame) { stream.process(frame); if (stream.isClosed()) removeStream(stream); }
private void processData(final IStream stream, DataFrame frame, ByteBuffer data) { ByteBufferDataInfo dataInfo = new ByteBufferDataInfo(data, frame.isClose()) { @Override public void consume(int delta) { super.consume(delta); flowControlStrategy.onDataConsumed(StandardSession.this, stream, this, delta); } }; flowControlStrategy.onDataReceived(this, stream, dataInfo); stream.process(dataInfo); if (stream.isClosed()) removeStream(stream); }
@Override public void succeeded() { bufferPool.release(buffer); super.succeeded(); if (frame.getType() == ControlFrameType.GO_AWAY) { // After sending a GO_AWAY we need to hard close the connection. // Recipients will know the last good stream id and act accordingly. close(); } IStream stream = getStream(); if (stream != null && stream.isClosed()) removeStream(stream); }
@Override public void onDataConsumed(ISession session, IStream stream, DataInfo dataInfo, int delta) { // This is the algorithm for flow control. // This method may be called multiple times with delta=1, but we only send a window // update when the whole dataInfo has been consumed. // Other policies may be to send window updates when consumed() is greater than // a certain threshold, etc. but for now the policy is not pluggable for simplicity. // Note that the frequency of window updates depends on the read buffer, that // should not be too smaller than the window size to avoid frequent window updates. // Therefore, a pluggable policy should be able to modify the read buffer capacity. int length = dataInfo.length(); if (dataInfo.consumed() == length && !stream.isClosed() && length > 0) { WindowUpdateFrame windowUpdateFrame = new WindowUpdateFrame(session.getVersion(), stream.getId(), length); session.control(stream, windowUpdateFrame, 0, TimeUnit.MILLISECONDS, Callback.Adapter.INSTANCE); } } }
@Override public void succeeded() { bufferPool.release(buffer); IStream stream = getStream(); dataInfo.consume(size); flowControlStrategy.updateWindow(StandardSession.this, stream, -size); if (dataInfo.available() > 0) { // We have written a frame out of this DataInfo, but there is more to write. // We need to keep the correct ordering of frames, to avoid that another // DataInfo for the same stream is written before this one is finished. flush(this, flusher.prepend(this)); } else { super.succeeded(); stream.updateCloseState(dataInfo.isClose(), true); if (stream.isClosed()) removeStream(stream); } }
if (!stream.isClosed()) stream.getAssociatedStream().associate(stream);
private void processSyn(SessionFrameListener listener, IStream stream, SynStreamFrame frame) { stream.process(frame); // Update the last stream id before calling the application (which may send a GO_AWAY) updateLastStreamId(stream); StreamFrameListener streamListener; if (stream.isUnidirectional()) { PushInfo pushInfo = new PushInfo(frame.getHeaders(), frame.isClose()); streamListener = notifyOnPush(stream.getAssociatedStream().getStreamFrameListener(), stream, pushInfo); } else { SynInfo synInfo = new SynInfo(frame.getHeaders(), frame.isClose(), frame.getPriority()); streamListener = notifyOnSyn(listener, stream, synInfo); } stream.setStreamFrameListener(streamListener); // The onSyn() listener may have sent a frame that closed the stream if (stream.isClosed()) removeStream(stream); }