Author: markt Date: Mon Jul 7 12:59:05 2014 New Revision: 1608443 URL: http://svn.apache.org/r1608443 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56698 When persisting idle sessions, only persist newly idle sessions. Patch provided by Felix Schumacher.
Added: tomcat/trunk/test/org/apache/catalina/session/TestPersistentManager.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/session/PersistentManagerBase.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/session/PersistentManagerBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/PersistentManagerBase.java?rev=1608443&r1=1608442&r2=1608443&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/PersistentManagerBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/PersistentManagerBase.java Mon Jul 7 12:59:05 2014 @@ -135,6 +135,12 @@ public abstract class PersistentManagerB */ 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. @@ -988,6 +994,12 @@ public abstract class PersistentManagerB synchronized (session) { if (!session.isValid()) continue; + long lastAccessedTime = session.getLastAccessedTime(); + 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 +1013,8 @@ public abstract class PersistentManagerB } catch (IOException e) { // This is logged in writeSession() } + session.setNote(PERSISTED_LAST_ACCESSED_TIME, + Long.valueOf(lastAccessedTime)); } } } Added: tomcat/trunk/test/org/apache/catalina/session/TestPersistentManager.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/session/TestPersistentManager.java?rev=1608443&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/catalina/session/TestPersistentManager.java (added) +++ tomcat/trunk/test/org/apache/catalina/session/TestPersistentManager.java Mon Jul 7 12:59:05 2014 @@ -0,0 +1,187 @@ +/* + * 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 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); + 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<>(); + + 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()); + } + + } +} \ No newline at end of file Propchange: tomcat/trunk/test/org/apache/catalina/session/TestPersistentManager.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1608443&r1=1608442&r2=1608443&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Mon Jul 7 12:59:05 2014 @@ -118,6 +118,10 @@ <code>HttpServletRequest.getPathTranslated()</code> returns a value that is based on the modified PathInfo. (markt) </fix> + <fix> + <bug>56698</bug>: When persisting idle sessions, only persist newly idle + sessions. Patch provided by Felix Schumacher. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org