This is an automated email from the ASF dual-hosted git repository. markt-asf pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 3a1bdd7d90e5a93a5ce04bc778cbf292b3fac92c Author: sainadh777 <[email protected]> AuthorDate: Mon Aug 17 03:52:34 2026 -0700 Use LRU order for persistent session swaps (#1045) --- .../catalina/session/PersistentManagerBase.java | 3 +- .../catalina/session/TestPersistentManager.java | 54 ++++++++++++++++++++++ webapps/docs/changelog.xml | 5 ++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/java/org/apache/catalina/session/PersistentManagerBase.java b/java/org/apache/catalina/session/PersistentManagerBase.java index b994ca4a5f..7595f14f67 100644 --- a/java/org/apache/catalina/session/PersistentManagerBase.java +++ b/java/org/apache/catalina/session/PersistentManagerBase.java @@ -21,6 +21,7 @@ import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -928,7 +929,6 @@ public abstract class PersistentManagerBase extends ManagerBase implements Store Session[] sessions = findSessions(); - // FIXME: Smarter algorithm (LRU) int limit = (int) (getMaxActiveSessions() * 0.9); if (limit >= sessions.length) { @@ -940,6 +940,7 @@ public abstract class PersistentManagerBase extends ManagerBase implements Store } int toswap = sessions.length - limit; + Arrays.sort(sessions, Comparator.comparingLong(Session::getLastAccessedTimeInternal)); for (int i = 0; i < sessions.length && toswap > 0; i++) { StandardSession session = (StandardSession) sessions[i]; diff --git a/test/org/apache/catalina/session/TestPersistentManager.java b/test/org/apache/catalina/session/TestPersistentManager.java index 9d60256ca3..320234d09a 100644 --- a/test/org/apache/catalina/session/TestPersistentManager.java +++ b/test/org/apache/catalina/session/TestPersistentManager.java @@ -71,6 +71,38 @@ public class TestPersistentManager { Assert.assertEquals(3, manager.getActiveSessionsFull()); } + @Test + public void testMaxActiveSwapUsesLeastRecentlyUsed() throws Exception { + OrderedPersistentManager manager = new OrderedPersistentManager(); + TesterStore store = new TesterStore(); + manager.setStore(store); + + Host host = new TesterHost(); + Context context = new TesterContext(); + context.setParent(host); + + manager.setContext(context); + manager.setMaxActiveSessions(3); + manager.setMinIdleSwap(0); + + manager.start(); + + StandardSession oldest = (StandardSession) manager.createSession("oldest"); + StandardSession middle = (StandardSession) manager.createSession("middle"); + StandardSession newest = (StandardSession) manager.createSession("newest"); + + long now = System.currentTimeMillis(); + oldest.lastAccessedTime = now - 30000; + middle.lastAccessedTime = now - 20000; + newest.lastAccessedTime = now - 10000; + + manager.setOrderedSessions(newest, middle, oldest); + manager.processMaxActiveSwaps(); + + Assert.assertEquals(1, store.getSavedIds().size()); + Assert.assertEquals("oldest", store.getSavedIds().get(0)); + } + @Test public void testBug62175() throws Exception { PersistentManager manager = new PersistentManager(); @@ -138,6 +170,28 @@ public class TestPersistentManager { } } + private static class OrderedPersistentManager extends PersistentManagerBase { + + private Session[] orderedSessions; + + void setOrderedSessions(Session... orderedSessions) { + this.orderedSessions = orderedSessions; + } + + @Override + public Session[] findSessions() { + if (orderedSessions == null) { + return super.findSessions(); + } + return orderedSessions; + } + + @Override + public String getName() { + return "OrderedPersistentManager"; + } + } + private StandardSession timedOutSession(PersistentManager manager, AtomicInteger counter) { StandardSession timedOutSession = new StandardSession(manager) { private static final long serialVersionUID = -5910605558747844210L; diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index f6dc27902e..ce4ee77395 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -122,6 +122,11 @@ Ensure that capture groups from a <code>RewriteCond</code> always reflect the result of the current request. (markt) </fix> + <fix> + When a <code>PersistentManager</code> needs to reduce the number of + active sessions, swap out the least recently used eligible sessions + first. Pull request <pr>1045</pr> provided by sainadh777. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
