public boolean onSessionTimeout(Throwable failure) { ISession session = getSession(); // Compute whether all requests are idle. boolean result = session.getStreams().stream() .map(stream -> (IStream)stream) .map(stream -> (HttpChannelOverHTTP2)stream.getAttachment()) .filter(Objects::nonNull) .map(HttpChannelOverHTTP2::isRequestIdle) .reduce(true, Boolean::logicalAnd); if (LOG.isDebugEnabled()) LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", session, failure); return result; }
@Override public long onFlushed(long bytes) throws IOException { long flushed = Math.min(frameRemaining, bytes); if (LOG.isDebugEnabled()) LOG.debug("Flushed {}/{} frame bytes for {}", flushed, bytes, this); frameRemaining -= flushed; // We should only forward data (not frame) bytes, // but we trade precision for simplicity. Object channel = stream.getAttachment(); if (channel instanceof WriteFlusher.Listener) ((WriteFlusher.Listener)channel).onFlushed(flushed); return bytes - flushed; }
@Override public long onFlushed(long bytes) throws IOException { long flushed = Math.min(frameRemaining, bytes); if (LOG.isDebugEnabled()) LOG.debug("Flushed {}/{} frame bytes for {}", flushed, bytes, this); frameRemaining -= flushed; // We should only forward data (not frame) bytes, // but we trade precision for simplicity. Object channel = stream.getAttachment(); if (channel instanceof WriteFlusher.Listener) ((WriteFlusher.Listener)channel).onFlushed(flushed); return bytes - flushed; }
public void onTrailers(IStream stream, HeadersFrame frame) { if (LOG.isDebugEnabled()) LOG.debug("Processing trailers {} on {}", frame, stream); HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); if (channel != null) { Runnable task = channel.onRequestTrailers(frame); if (task != null) offerTask(task, false); } }
public boolean onStreamTimeout(IStream stream, Throwable failure) { HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); boolean result = channel != null && channel.onStreamTimeout(failure, task -> offerTask(task, true)); if (LOG.isDebugEnabled()) LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", stream, failure); return result; }
public void onData(IStream stream, DataFrame frame, Callback callback) { if (LOG.isDebugEnabled()) LOG.debug("Processing {} on {}", frame, stream); HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); if (channel != null) { Runnable task = channel.onRequestContent(frame, callback); if (task != null) offerTask(task, false); } else { callback.failed(new IOException("channel_not_found")); } }
public void onStreamFailure(IStream stream, Throwable failure, Callback callback) { if (LOG.isDebugEnabled()) LOG.debug("Processing failure on {}: {}", stream, failure); HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); if (channel != null) { Runnable task = channel.onFailure(failure, callback); if (task != null) offerTask(task, true); } else { callback.succeeded(); } }
@Override public void onCompleted() { // If the stream is not closed, it is still reading the request content. // Send a reset to the other end so that it stops sending data. if (!stream.isClosed()) { if (LOG.isDebugEnabled()) LOG.debug("HTTP2 Response #{}: unconsumed request content, resetting stream", stream.getId()); stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP); } // Consume the existing queued data frames to // avoid stalling the session flow control. HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); if (channel != null) channel.consumeInput(); }