Search in sources :

Example 6 with ISession

use of org.eclipse.jetty.http2.ISession in project jetty.project by eclipse.

the class HTTP2ServerConnection method onSessionTimeout.

public boolean onSessionTimeout(Throwable failure) {
    ISession session = getSession();
    boolean result = true;
    for (Stream stream : session.getStreams()) {
        HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2) stream.getAttribute(IStream.CHANNEL_ATTRIBUTE);
        if (channel != null)
            result &= !channel.isRequestHandled();
    }
    if (LOG.isDebugEnabled())
        LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", session, failure);
    return result;
}
Also used : ISession(org.eclipse.jetty.http2.ISession) Stream(org.eclipse.jetty.http2.api.Stream) IStream(org.eclipse.jetty.http2.IStream)

Example 7 with ISession

use of org.eclipse.jetty.http2.ISession in project jetty.project by eclipse.

the class AbstractFlowControlStrategy method updateInitialStreamWindow.

@Override
public void updateInitialStreamWindow(ISession session, int initialStreamWindow, boolean local) {
    int previousInitialStreamWindow;
    if (local) {
        previousInitialStreamWindow = getInitialStreamRecvWindow();
        this.initialStreamRecvWindow = initialStreamWindow;
    } else {
        previousInitialStreamWindow = getInitialStreamSendWindow();
        this.initialStreamSendWindow = initialStreamWindow;
    }
    int delta = initialStreamWindow - previousInitialStreamWindow;
    // SPEC: updates of the initial window size only affect stream windows, not session's.
    for (Stream stream : session.getStreams()) {
        if (local) {
            ((IStream) stream).updateRecvWindow(delta);
            if (LOG.isDebugEnabled())
                LOG.debug("Updated initial stream recv window {} -> {} for {}", previousInitialStreamWindow, initialStreamWindow, stream);
        } else {
            session.onWindowUpdate((IStream) stream, new WindowUpdateFrame(stream.getId(), delta));
        }
    }
}
Also used : WindowUpdateFrame(org.eclipse.jetty.http2.frames.WindowUpdateFrame) Stream(org.eclipse.jetty.http2.api.Stream)

Example 8 with ISession

use of org.eclipse.jetty.http2.ISession in project jetty.project by eclipse.

the class BufferingFlowControlStrategy method onDataConsumed.

@Override
public void onDataConsumed(ISession session, IStream stream, int length) {
    if (length <= 0)
        return;
    float ratio = bufferRatio;
    WindowUpdateFrame windowFrame = null;
    int level = sessionLevel.addAndGet(length);
    int maxLevel = (int) (maxSessionRecvWindow.get() * ratio);
    if (level > maxLevel) {
        if (sessionLevel.compareAndSet(level, 0)) {
            session.updateRecvWindow(level);
            if (LOG.isDebugEnabled())
                LOG.debug("Data consumed, {} bytes, updated session recv window by {}/{} for {}", length, level, maxLevel, session);
            windowFrame = new WindowUpdateFrame(0, level);
        } else {
            if (LOG.isDebugEnabled())
                LOG.debug("Data consumed, {} bytes, concurrent session recv window level {}/{} for {}", length, sessionLevel, maxLevel, session);
        }
    } else {
        if (LOG.isDebugEnabled())
            LOG.debug("Data consumed, {} bytes, session recv window level {}/{} for {}", length, level, maxLevel, session);
    }
    Frame[] windowFrames = Frame.EMPTY_ARRAY;
    if (stream != null) {
        if (stream.isClosed()) {
            if (LOG.isDebugEnabled())
                LOG.debug("Data consumed, {} bytes, ignoring update stream recv window for closed {}", length, stream);
        } else {
            AtomicInteger streamLevel = streamLevels.get(stream);
            if (streamLevel != null) {
                level = streamLevel.addAndGet(length);
                maxLevel = (int) (getInitialStreamRecvWindow() * ratio);
                if (level > maxLevel) {
                    level = streamLevel.getAndSet(0);
                    stream.updateRecvWindow(level);
                    if (LOG.isDebugEnabled())
                        LOG.debug("Data consumed, {} bytes, updated stream recv window by {}/{} for {}", length, level, maxLevel, stream);
                    WindowUpdateFrame frame = new WindowUpdateFrame(stream.getId(), level);
                    if (windowFrame == null)
                        windowFrame = frame;
                    else
                        windowFrames = new Frame[] { frame };
                } else {
                    if (LOG.isDebugEnabled())
                        LOG.debug("Data consumed, {} bytes, stream recv window level {}/{} for {}", length, level, maxLevel, stream);
                }
            }
        }
    }
    if (windowFrame != null)
        session.frames(stream, Callback.NOOP, windowFrame, windowFrames);
}
Also used : WindowUpdateFrame(org.eclipse.jetty.http2.frames.WindowUpdateFrame) WindowUpdateFrame(org.eclipse.jetty.http2.frames.WindowUpdateFrame) Frame(org.eclipse.jetty.http2.frames.Frame) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 9 with ISession

use of org.eclipse.jetty.http2.ISession in project jetty.project by eclipse.

the class FlowControlStalledTest method testSessionStalledIsInvokedOnlyOnce.

@Test
public void testSessionStalledIsInvokedOnlyOnce() throws Exception {
    AtomicReference<CountDownLatch> stallLatch = new AtomicReference<>(new CountDownLatch(1));
    CountDownLatch unstallLatch = new CountDownLatch(1);
    start(() -> new BufferingFlowControlStrategy(0.5f) {

        @Override
        public void onSessionStalled(ISession session) {
            super.onSessionStalled(session);
            stallLatch.get().countDown();
        }

        @Override
        protected void onSessionUnstalled(ISession session) {
            super.onSessionUnstalled(session);
            unstallLatch.countDown();
        }
    }, new ServerSessionListener.Adapter() {

        @Override
        public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
            MetaData.Request request = (MetaData.Request) frame.getMetaData();
            MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields());
            if (request.getURIString().endsWith("/stall")) {
                stream.headers(new HeadersFrame(stream.getId(), response, null, false), new Callback() {

                    @Override
                    public void succeeded() {
                        // Send a large chunk of data so the session gets stalled.
                        ByteBuffer data = ByteBuffer.allocate(FlowControlStrategy.DEFAULT_WINDOW_SIZE + 1);
                        stream.data(new DataFrame(stream.getId(), data, true), NOOP);
                    }
                });
            } else {
                stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
            }
            return null;
        }
    });
    // Use a large stream window so that only the session gets stalled.
    client.setInitialStreamRecvWindow(5 * FlowControlStrategy.DEFAULT_WINDOW_SIZE);
    Session session = newClient(new Session.Listener.Adapter() {

        @Override
        public Map<Integer, Integer> onPreface(Session session) {
            Map<Integer, Integer> settings = new HashMap<>();
            settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, client.getInitialStreamRecvWindow());
            return settings;
        }
    });
    CountDownLatch latch = new CountDownLatch(1);
    Queue<Callback> callbacks = new ArrayDeque<>();
    MetaData.Request request = newRequest("GET", "/stall", new HttpFields());
    session.newStream(new HeadersFrame(request, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() {

        @Override
        public void onData(Stream stream, DataFrame frame, Callback callback) {
            callbacks.offer(callback);
            if (frame.isEndStream())
                latch.countDown();
        }
    });
    Assert.assertTrue(stallLatch.get().await(5, TimeUnit.SECONDS));
    // The session is now stalled, check that writing a second stream
    // does not result in the session be notified again of being stalled.
    stallLatch.set(new CountDownLatch(1));
    request = newRequest("GET", "/", new HttpFields());
    session.newStream(new HeadersFrame(request, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter());
    Assert.assertFalse(stallLatch.get().await(1, TimeUnit.SECONDS));
    // Consume all data.
    while (!latch.await(10, TimeUnit.MILLISECONDS)) {
        Callback callback = callbacks.poll();
        if (callback != null)
            callback.succeeded();
    }
    // Make sure the unstall callback is invoked.
    Assert.assertTrue(unstallLatch.await(5, TimeUnit.SECONDS));
}
Also used : ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) Stream(org.eclipse.jetty.http2.api.Stream) IStream(org.eclipse.jetty.http2.IStream) BufferingFlowControlStrategy(org.eclipse.jetty.http2.BufferingFlowControlStrategy) AtomicReference(java.util.concurrent.atomic.AtomicReference) DataFrame(org.eclipse.jetty.http2.frames.DataFrame) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) ArrayDeque(java.util.ArrayDeque) Promise(org.eclipse.jetty.util.Promise) FuturePromise(org.eclipse.jetty.util.FuturePromise) ISession(org.eclipse.jetty.http2.ISession) Callback(org.eclipse.jetty.util.Callback) HashMap(java.util.HashMap) Map(java.util.Map) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) Session(org.eclipse.jetty.http2.api.Session) ISession(org.eclipse.jetty.http2.ISession) Test(org.junit.Test)

Aggregations

Stream (org.eclipse.jetty.http2.api.Stream)7 ISession (org.eclipse.jetty.http2.ISession)6 ByteBuffer (java.nio.ByteBuffer)5 CountDownLatch (java.util.concurrent.CountDownLatch)5 HttpFields (org.eclipse.jetty.http.HttpFields)5 MetaData (org.eclipse.jetty.http.MetaData)5 Session (org.eclipse.jetty.http2.api.Session)5 ServerSessionListener (org.eclipse.jetty.http2.api.server.ServerSessionListener)5 DataFrame (org.eclipse.jetty.http2.frames.DataFrame)5 HeadersFrame (org.eclipse.jetty.http2.frames.HeadersFrame)5 Callback (org.eclipse.jetty.util.Callback)5 FuturePromise (org.eclipse.jetty.util.FuturePromise)5 Test (org.junit.Test)5 IStream (org.eclipse.jetty.http2.IStream)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 WindowUpdateFrame (org.eclipse.jetty.http2.frames.WindowUpdateFrame)3 FutureCallback (org.eclipse.jetty.util.FutureCallback)3 ServletOutputStream (javax.servlet.ServletOutputStream)2 WriteListener (javax.servlet.WriteListener)2