ASF Bugzilla – Attachment 31793 Details for
Bug 56698
Sessions will be backed up too often by PersistentManager
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Add a flag to PersistentManager whether it will save idle sessions once or always
save-only-once.patch (text/plain), 12.29 KB, created by
Felix Schumacher
on 2014-07-05 15:16:58 UTC
(
hide
)
Description:
Add a flag to PersistentManager whether it will save idle sessions once or always
Filename:
MIME Type:
Creator:
Felix Schumacher
Created:
2014-07-05 15:16:58 UTC
Size:
12.29 KB
patch
obsolete
>diff --git a/java/org/apache/catalina/session/PersistentManagerBase.java b/java/org/apache/catalina/session/PersistentManagerBase.java >index a562757..fde08ba 100644 >--- a/java/org/apache/catalina/session/PersistentManagerBase.java >+++ b/java/org/apache/catalina/session/PersistentManagerBase.java >@@ -135,6 +135,11 @@ public abstract class PersistentManagerBase extends ManagerBase > */ > private static final String name = "PersistentManagerBase"; > >+ /** >+ * Key of the note of a session in which the timestamp of last backup is stored. >+ */ >+ private static final String PERSISTED_LAST_ACCESSED_TIME = "org.apache.catalina.session.PersistentManagerBase.persistedLastAccessedTime"; >+ > > /** > * Store object which will manage the Session store. >@@ -177,6 +182,12 @@ public abstract class PersistentManagerBase extends ManagerBase > private final Map<String,Object> sessionSwapInLocks = new HashMap<>(); > > >+ /** >+ * Only backup session once, while lastAccessedTime of the session is not changed >+ */ >+ protected boolean backupOnceAfterAccess = false; >+ >+ > // ------------------------------------------------------------- Properties > > >@@ -284,6 +295,33 @@ public abstract class PersistentManagerBase extends ManagerBase > > > /** >+ * Flag which determines if a session will be backed up only once after >+ * reaching maxIdleBackup with same lastAccessedTime >+ */ >+ public boolean getBackupOnceAfterAccess() { >+ >+ return this.backupOnceAfterAccess; >+ >+ } >+ >+ /** >+ * Sets the flag, which determines if a session will be backed up only once >+ * after reaching maxIdleBackup while lastAccessedTime is not changed, or >+ * everytime when sessions will be checked for backup >+ */ >+ public void setBackupOnceAfterAccess(boolean backupOnce) { >+ >+ if (this.backupOnceAfterAccess == backupOnce) >+ return; >+ boolean oldBackupOnceAfterAccess = this.backupOnceAfterAccess; >+ this.backupOnceAfterAccess = backupOnce; >+ support.firePropertyChange("backupOnceAfterAccess", >+ Boolean.valueOf(oldBackupOnceAfterAccess), >+ Boolean.valueOf(this.backupOnceAfterAccess)); >+ >+ } >+ >+ /** > * Return true, if the session id is loaded in memory > * otherwise false is returned > * >@@ -988,6 +1026,13 @@ public abstract class PersistentManagerBase extends ManagerBase > synchronized (session) { > if (!session.isValid()) > continue; >+ long lastAccessedTime = session.getLastAccessedTime(); >+ if (backupOnceAfterAccess) { >+ Long persistedLastAccessedTime = (Long) session.getNote(PERSISTED_LAST_ACCESSED_TIME); >+ if (persistedLastAccessedTime != null && >+ lastAccessedTime == persistedLastAccessedTime.longValue()) >+ continue; >+ } > int timeIdle = (int) (session.getIdleTime() / 1000L); > if (timeIdle > maxIdleBackup) { > if (log.isDebugEnabled()) >@@ -1001,6 +1046,8 @@ public abstract class PersistentManagerBase extends ManagerBase > } catch (IOException e) { > // This is logged in writeSession() > } >+ if (backupOnceAfterAccess) >+ session.setNote(PERSISTED_LAST_ACCESSED_TIME, Long.valueOf(lastAccessedTime)); > } > } > } >diff --git a/java/org/apache/catalina/session/mbeans-descriptors.xml b/java/org/apache/catalina/session/mbeans-descriptors.xml >index 4f9b01e..c32f6f3 100644 >--- a/java/org/apache/catalina/session/mbeans-descriptors.xml >+++ b/java/org/apache/catalina/session/mbeans-descriptors.xml >@@ -215,6 +215,10 @@ > type="int" > writeable="false"/> > >+ <attribute name="backupOnceAfterAccess" >+ description="Flag whether sessions should be saved only once after access" >+ type="boolean"/> >+ > <attribute name="className" > description="Fully qualified class name of the managed object" > type="java.lang.String" >diff --git a/test/org/apache/catalina/session/TestPersistentManager.java b/test/org/apache/catalina/session/TestPersistentManager.java >new file mode 100644 >index 0000000..9e6b5c0 >--- /dev/null >+++ b/test/org/apache/catalina/session/TestPersistentManager.java >@@ -0,0 +1,221 @@ >+/* >+ * Licensed to the Apache Software Foundation (ASF) under one or more >+ * contributor license agreements. See the NOTICE file distributed with >+ * this work for additional information regarding copyright ownership. >+ * The ASF licenses this file to You under the Apache License, Version 2.0 >+ * (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+package org.apache.catalina.session; >+ >+import java.beans.PropertyChangeListener; >+import java.io.IOException; >+import java.util.ArrayList; >+import java.util.Arrays; >+import java.util.List; >+ >+import javax.servlet.ServletException; >+import javax.servlet.http.HttpServlet; >+import javax.servlet.http.HttpServletRequest; >+import javax.servlet.http.HttpServletResponse; >+ >+import org.apache.catalina.Context; >+import org.apache.catalina.LifecycleException; >+import org.apache.catalina.Manager; >+import org.apache.catalina.Session; >+import org.apache.catalina.Store; >+import org.apache.catalina.startup.Tomcat; >+import org.apache.catalina.startup.TomcatBaseTest; >+import org.junit.After; >+import org.junit.Assert; >+import org.junit.Before; >+import org.junit.Test; >+ >+public class TestPersistentManager extends TomcatBaseTest { >+ >+ private final String ACTIVITY_CHECK = "org.apache.catalina.session.StandardSession.ACTIVITY_CHECK"; >+ >+ private String oldActivityCheck; >+ >+ @Before >+ public void setActivityCheck() { >+ oldActivityCheck = System.setProperty(ACTIVITY_CHECK, "true"); >+ } >+ >+ @After >+ public void resetActivityCheck() { >+ if (oldActivityCheck != null) { >+ System.setProperty(ACTIVITY_CHECK, oldActivityCheck); >+ } else { >+ System.clearProperty(ACTIVITY_CHECK); >+ } >+ } >+ >+ @Test >+ public void backsUpEveryTime() throws Exception { >+ >+ // Setup Tomcat instance >+ Tomcat tomcat = getTomcatInstance(); >+ // Must have a real docBase - just use temp >+ Context ctx = tomcat.addContext("", >+ System.getProperty("java.io.tmpdir")); >+ >+ Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet()); >+ ctx.addServletMapping("/dummy", "DummyServlet"); >+ >+ PersistentManager manager = new PersistentManager(); >+ DummyStore store = new DummyStore(); >+ >+ manager.setStore(store); >+ manager.setMaxIdleBackup(0); >+ manager.setDistributable(true); >+ ctx.setManager(manager); >+ tomcat.start(); >+ String sessionId = getUrl("http://localhost:" + getPort() + "/dummy") >+ .toString(); >+ sleepABit(); >+ >+ manager.processPersistenceChecks(); >+ Assert.assertEquals(store.getSavedIds(), Arrays.asList(sessionId)); >+ >+ // session was not access, but will be saved anyway >+ manager.processPersistenceChecks(); >+ Assert.assertEquals(store.getSavedIds(), >+ Arrays.asList(sessionId, sessionId)); >+ } >+ >+ @Test >+ public void backsUpOnce() throws IOException, LifecycleException { >+ >+ // Setup Tomcat instance >+ Tomcat tomcat = getTomcatInstance(); >+ // Must have a real docBase - just use temp >+ Context ctx = tomcat.addContext("", >+ System.getProperty("java.io.tmpdir")); >+ >+ Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet()); >+ ctx.addServletMapping("/dummy", "DummyServlet"); >+ >+ PersistentManager manager = new PersistentManager(); >+ DummyStore store = new DummyStore(); >+ >+ manager.setStore(store); >+ manager.setMaxIdleBackup(0); >+ manager.setDistributable(true); >+ manager.setBackupOnceAfterAccess(true); >+ ctx.setManager(manager); >+ tomcat.start(); >+ String sessionId = getUrl("http://localhost:" + getPort() + "/dummy") >+ .toString(); >+ sleepABit(); >+ >+ manager.processPersistenceChecks(); >+ Assert.assertEquals(Arrays.asList(sessionId), store.getSavedIds()); >+ >+ // session was not accessed, so no save will be performed >+ manager.processPersistenceChecks(); >+ Assert.assertEquals(Arrays.asList(sessionId), store.getSavedIds()); >+ >+ // access session >+ manager.findSession(sessionId).access(); >+ manager.findSession(sessionId).endAccess(); >+ sleepABit(); >+ >+ // session was accessed, so it will be saved once again >+ manager.processPersistenceChecks(); >+ Assert.assertEquals(Arrays.asList(sessionId, sessionId), >+ store.getSavedIds()); >+ >+ // session was not accessed, so once again no save will happen >+ manager.processPersistenceChecks(); >+ Assert.assertEquals(Arrays.asList(sessionId, sessionId), >+ store.getSavedIds()); >+ } >+ >+ private void sleepABit() { >+ try { >+ Thread.sleep(1000); >+ } catch (InterruptedException e) { >+ // ignore Interrupt >+ } >+ } >+ >+ private static class DummyServlet extends HttpServlet { >+ >+ private static final long serialVersionUID = -3696433049266123995L; >+ >+ @Override >+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) >+ throws ServletException, IOException { >+ resp.getWriter().print(req.getSession().getId()); >+ } >+ >+ } >+ >+ private static class DummyStore implements Store { >+ >+ private Manager manager; >+ private List<String> savedIds = new ArrayList<String>(); >+ >+ List<String> getSavedIds() { >+ return savedIds; >+ } >+ >+ @Override >+ public Manager getManager() { >+ return this.manager; >+ } >+ >+ @Override >+ public void setManager(Manager manager) { >+ this.manager = manager; >+ } >+ >+ @Override >+ public int getSize() throws IOException { >+ return 0; >+ } >+ >+ @Override >+ public void addPropertyChangeListener(PropertyChangeListener listener) { >+ } >+ >+ @Override >+ public String[] keys() throws IOException { >+ return null; >+ } >+ >+ @Override >+ public Session load(String id) throws ClassNotFoundException, >+ IOException { >+ // TODO Auto-generated method stub >+ return null; >+ } >+ >+ @Override >+ public void remove(String id) throws IOException { >+ } >+ >+ @Override >+ public void clear() throws IOException { >+ } >+ >+ @Override >+ public void removePropertyChangeListener(PropertyChangeListener listener) { >+ } >+ >+ @Override >+ public void save(Session session) throws IOException { >+ savedIds.add(session.getId()); >+ } >+ >+ } >+} >diff --git a/webapps/docs/config/manager.xml b/webapps/docs/config/manager.xml >index de97cfd..9509568 100644 >--- a/webapps/docs/config/manager.xml >+++ b/webapps/docs/config/manager.xml >@@ -200,6 +200,13 @@ > > <attributes> > >+ <attribute name="backupOnceAfterAccess" required="false"> >+ <p>If sessions should be backed up only once while not accessed. If >+ <code>false</code> all sessions which are not accessed for >+ <code>maxIdelBackup</code> will be backed up every time. Default is >+ <code>false</code>.</p> >+ </attribute> >+ > <attribute name="className" required="true"> > <p>It has the same meaning as described in the > <a href="#Common_Attributes">Common Attributes</a> above.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 56698
:
31793
|
31798
|
31799