@Override public void complete() { bufferPool.release(buffer); super.complete(); 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); }
private void generateAndEnqueueControlFrame( IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback callback) { try { // Synchronization is necessary, since we may have concurrent replies // and those needs to be generated and enqueued atomically in order // to maintain a correct compression context synchronized (this) { ByteBuffer buffer = generator.control(frame); LOG.debug("Queuing {} on {}", frame, stream); ControlFrameBytes frameBytes = new ControlFrameBytes(stream, callback, frame, buffer); if (timeout > 0) frameBytes.task = scheduler.schedule(frameBytes, timeout, unit); // Special handling for PING frames, they must be sent as soon as possible if (ControlFrameType.PING == frame.getType()) prepend(frameBytes); else append(frameBytes); } } catch (Exception x) { notifyCallbackFailed(callback, x); } }
@Override public void onControlFrame(ControlFrame frame) { notifyIdle(idleListener, false); try { LOG.debug("Processing {}", frame); if (goAwaySent.get()) { LOG.debug("Skipped processing of {}", frame); return; } switch (frame.getType()) { case SYN_STREAM: { onSyn((SynStreamFrame) frame); break; } case SYN_REPLY: { onReply((SynReplyFrame) frame); break; } case RST_STREAM: { onRst((RstStreamFrame) frame); break; } case SETTINGS: { onSettings((SettingsFrame) frame); break; } case NOOP: { // Just ignore it break; } case PING: { onPing((PingFrame) frame); break; } case GO_AWAY: { onGoAway((GoAwayFrame) frame); break; } case HEADERS: { onHeaders((HeadersFrame) frame); break; } case WINDOW_UPDATE: { onWindowUpdate((WindowUpdateFrame) frame); break; } case CREDENTIAL: { onCredential((CredentialFrame) frame); break; } default: { throw new IllegalStateException(); } } } finally { notifyIdle(idleListener, true); } }