This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push:
new 9a59ef2717 Use LRU order for persistent session swaps (#1045)
9a59ef2717 is described below
commit 9a59ef27179803bf0f03f9ce517c58f8bb7b1029
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 019925cc8a..13d6a1fa7d 100644
--- a/java/org/apache/catalina/session/PersistentManagerBase.java
+++ b/java/org/apache/catalina/session/PersistentManagerBase.java
@@ -18,6 +18,7 @@ package org.apache.catalina.session;
import java.io.IOException;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -797,7 +798,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) {
@@ -809,6 +809,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 be95c26687..2f6518c370 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 6d8e0727aa..f92b88fe94 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -253,6 +253,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. (sainadh777)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]