From 88ac10439a8b5ec1c34aaab4ccbf0f590aee33f8 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 12 May 2021 01:29:38 +0200 Subject: [PATCH] Issue #6254 - Total timeout not enforced for queued requests. Updates after review. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/client/HttpDestination.java | 11 ++++++----- .../main/java/org/eclipse/jetty/io/CyclicTimeout.java | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java index f5a0a177272..2686b22cf95 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java @@ -567,14 +567,15 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest LOG.debug("{} timeouts check", this); long now = System.nanoTime(); - + long earliest = Long.MAX_VALUE; // Reset the earliest timeout so we can expire again. // A concurrent call to schedule(long) may lose an earliest // value, but the corresponding exchange is already enqueued // and will be seen by scanning the exchange queue below. - earliestTimeout.set(Long.MAX_VALUE); + earliestTimeout.set(earliest); - long earliest = Long.MAX_VALUE; + // Scan the message queue to abort expired exchanges + // and to find the exchange that expire the earliest. for (HttpExchange exchange : exchanges) { HttpRequest request = exchange.getRequest(); @@ -596,8 +597,8 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest // Schedule a timeout for the earliest exchange that may expire. // When the timeout expires, scan the exchange queue for the next // earliest exchange that may expire, and reschedule a new timeout. - long earliest = earliestTimeout.getAndUpdate(t -> Math.min(t, expiresAt)); - if (expiresAt < earliest) + long prevEarliest = earliestTimeout.getAndUpdate(t -> Math.min(t, expiresAt)); + if (expiresAt < prevEarliest) { // A new request expires earlier than previous requests, schedule it. long delay = Math.max(0, expiresAt - System.nanoTime()); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java b/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java index fae0374c403..60a04ec0b39 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java @@ -119,10 +119,12 @@ public abstract class CyclicTimeout implements Destroyable if (_timeout.compareAndSet(timeout, new Timeout(newTimeoutAt, wakeup))) { if (LOG.isDebugEnabled()) + { LOG.debug("Installed timeout in {} ms, {} wake up in {} ms", units.toMillis(delay), newWakeup != null ? "new" : "existing", TimeUnit.NANOSECONDS.toMillis(wakeup._at - now)); + } break; } }