From b1685981dadff2c45e1e1f3df4f86ecb5f1d0f9c Mon Sep 17 00:00:00 2001 From: Volodymyr Sorokin Date: Wed, 9 Oct 2024 15:03:17 +0300 Subject: [PATCH] Backport #7515 to 9.4 - Connection limit problem for "onAccepting" connections * Backport for the PR #12320 * Fixed `ManagedSelector.Accept` to emit the event "accept failed" when closed. * Fixed `ConnectionLimit` to close connections that exceed the maximum (may happen when the connector is configured with acceptors=0). --- .../org/eclipse/jetty/io/ManagedSelector.java | 19 ++++++++----------- .../eclipse/jetty/server/ConnectionLimit.java | 11 ++++++++--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java index b3b9b7326ff0..2b74c6979397 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java @@ -23,6 +23,7 @@ import java.net.ConnectException; import java.net.SocketTimeoutException; import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedChannelException; import java.nio.channels.ClosedSelectorException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; @@ -861,8 +862,8 @@ class Accept implements SelectorUpdate, Runnable, Closeable public void close() { if (LOG.isDebugEnabled()) - LOG.debug("closed accept of {}", channel); - IO.close(channel); + LOG.debug("Closed accept of {}", channel); + failed(new ClosedChannelException()); } @Override @@ -875,10 +876,9 @@ public void update(Selector selector) } catch (Throwable x) { - IO.close(channel); - _selectorManager.onAcceptFailed(channel, x); if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Could not register channel after accept {}", channel, x); + failed(x); } } @@ -887,23 +887,20 @@ public void run() { try { - createEndPoint(channel, key); _selectorManager.onAccepted(channel); + createEndPoint(channel, key); } catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Could not process accepted channel {}", channel, x); failed(x); } } - protected void failed(Throwable failure) + private void failed(Throwable failure) { IO.close(channel); - LOG.warn(String.valueOf(failure)); - if (LOG.isDebugEnabled()) - LOG.debug(failure); _selectorManager.onAcceptFailed(channel, failure); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java index a6bd5ddd49e5..b08867481449 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java @@ -28,6 +28,7 @@ import org.eclipse.jetty.io.Connection.Listener; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.SelectorManager; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.Name; @@ -172,9 +173,10 @@ protected void doStop() throws Exception } } - protected void check() + protected boolean check() { - if ((_accepting.size() + _connections) >= _maxConnections) + int total = _accepting.size() + _connections; + if (total >= _maxConnections) { if (!_limiting) { @@ -182,6 +184,7 @@ protected void check() LOG.info("Connection Limit({}) reached for {}", _maxConnections, _connectors); limit(); } + return total > _maxConnections; } else { @@ -191,6 +194,7 @@ protected void check() LOG.info("Connection Limit({}) cleared for {}", _maxConnections, _connectors); unlimit(); } + return false; } } @@ -234,7 +238,8 @@ public void onAccepting(SelectableChannel channel) _accepting.add(channel); if (LOG.isDebugEnabled()) LOG.debug("onAccepting ({}+{}) < {} {}", _accepting.size(), _connections, _maxConnections, channel); - check(); + if (check()) + IO.close(channel); } }