Author: kfujino Date: Tue Apr 17 06:23:21 2012 New Revision: 1326941 URL: http://svn.apache.org/viewvc?rev=1326941&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=53087. In order to avoid that a backup node expire a session, replicate session access time in BackupManager.
Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/ha/session/DeltaSession.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/ha/session/DeltaSession.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/ha/session/DeltaSession.java?rev=1326941&r1=1326940&r2=1326941&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/ha/session/DeltaSession.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/ha/session/DeltaSession.java Tue Apr 17 06:23:21 2012 @@ -222,6 +222,30 @@ public class DeltaSession extends Standa this.endAccess(); } } + + /** + * If this returns true, to replicate that an object has been accessed + * @return boolean + */ + @Override + public boolean isAccessReplicate() { + long replDelta = System.currentTimeMillis() - getLastTimeReplicated(); + if (maxInactiveInterval >=0 && replDelta > (maxInactiveInterval * 1000)) { + return true; + } + return false; + } + + /** + * Access to an existing object. + */ + @Override + public void accessEntry() { + this.access(); + this.setPrimarySession(false); + this.endAccess(); + } + // ----------------------------------------------------- Session Properties /** @@ -843,7 +867,8 @@ public class DeltaSession extends Standa } } - protected long getLastTimeReplicated() { + @Override + public long getLastTimeReplicated() { return lastTimeReplicated; } @@ -852,7 +877,8 @@ public class DeltaSession extends Standa return version; } - protected void setLastTimeReplicated(long lastTimeReplicated) { + @Override + public void setLastTimeReplicated(long lastTimeReplicated) { this.lastTimeReplicated = lastTimeReplicated; } Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java?rev=1326941&r1=1326940&r2=1326941&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java Tue Apr 17 06:23:21 2012 @@ -402,8 +402,10 @@ public abstract class AbstractReplicated if ( !entry.isSerializable() ) return; if (entry.isPrimary() && entry.getBackupNodes()!= null && entry.getBackupNodes().length > 0) { Object value = entry.getValue(); - //check to see if we need to replicate this object isDirty()||complete - boolean repl = complete || ( (value instanceof ReplicatedMapEntry) && ( (ReplicatedMapEntry) value).isDirty()); + //check to see if we need to replicate this object isDirty()||complete || isAccessReplicate() + boolean isDirty = ((value instanceof ReplicatedMapEntry) && ((ReplicatedMapEntry) value).isDirty()); + boolean isAccess = ((value instanceof ReplicatedMapEntry) && ((ReplicatedMapEntry) value).isAccessReplicate()); + boolean repl = complete || isDirty || isAccess; if (!repl) { if ( log.isTraceEnabled() ) @@ -412,9 +414,9 @@ public abstract class AbstractReplicated return; } //check to see if the message is diffable - boolean diff = ( (value instanceof ReplicatedMapEntry) && ( (ReplicatedMapEntry) value).isDiffable()); + boolean diff = ((value instanceof ReplicatedMapEntry) && ((ReplicatedMapEntry) value).isDiffable()); MapMessage msg = null; - if (diff) { + if (diff && isDirty) { ReplicatedMapEntry rentry = (ReplicatedMapEntry)entry.getValue(); try { rentry.lock(); @@ -432,6 +434,12 @@ public abstract class AbstractReplicated } } + if (msg == null && isAccess) { + //construct a access message + msg = new MapMessage(mapContextName, MapMessage.MSG_ACCESS, + false, (Serializable) entry.getKey(), null, null, entry.getPrimary(), + entry.getBackupNodes()); + } if (msg == null) { //construct a complete msg = new MapMessage(mapContextName, MapMessage.MSG_BACKUP, @@ -442,6 +450,9 @@ public abstract class AbstractReplicated } try { if ( channel!=null && entry.getBackupNodes()!= null && entry.getBackupNodes().length > 0 ) { + if ((entry.getValue() instanceof ReplicatedMapEntry)) { + ((ReplicatedMapEntry)entry.getValue()).setLastTimeReplicated(System.currentTimeMillis()); + } channel.send(entry.getBackupNodes(), msg, channelSendOptions); } } catch (ChannelException x) { @@ -670,6 +681,17 @@ public abstract class AbstractReplicated } //end if super.put(entry.getKey(), entry); } //end if + + if (mapmsg.getMsgType() == MapMessage.MSG_ACCESS) { + MapEntry entry = (MapEntry)super.get(mapmsg.getKey()); + if (entry != null) { + entry.setBackupNodes(mapmsg.getBackupNodes()); + entry.setPrimary(mapmsg.getPrimary()); + if (entry.getValue() instanceof ReplicatedMapEntry) { + ((ReplicatedMapEntry) entry.getValue()).accessEntry(); + } + } + } } @Override @@ -1277,6 +1299,7 @@ public abstract class AbstractReplicated public static final int MSG_INIT = 8; public static final int MSG_COPY = 9; public static final int MSG_STATE_COPY = 10; + public static final int MSG_ACCESS = 11; private byte[] mapId; private int msgtype; @@ -1314,6 +1337,7 @@ public abstract class AbstractReplicated case MSG_INIT: return "MSG_INIT"; case MSG_STATE_COPY: return "MSG_STATE_COPY"; case MSG_COPY: return "MSG_COPY"; + case MSG_ACCESS: return "MSG_ACCESS"; default : return "UNKNOWN"; } } Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java?rev=1326941&r1=1326940&r2=1326941&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java Tue Apr 17 06:23:21 2012 @@ -118,5 +118,27 @@ public interface ReplicatedMapEntry exte */ public void setVersion(long version); + /** + * Return the last replicate time. + * @return + */ + public long getLastTimeReplicated(); + + /** + * Set the last replicate time. + * @param lastTimeReplicated + */ + public void setLastTimeReplicated(long lastTimeReplicated); + + /** + * If this returns true, to replicate that an object has been accessed + * @return boolean + */ + public boolean isAccessReplicate(); + + /** + * Access to an existing object. + */ + public void accessEntry(); } \ No newline at end of file Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1326941&r1=1326940&r2=1326941&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Tue Apr 17 06:23:21 2012 @@ -82,6 +82,10 @@ <fix> Avoid NPE when reload if a state of a BackupManager is FAILED. (kfujino) </fix> + <fix> + <bug>53087</bug>: In order to avoid that a backup node expire a session, + replicate session access time in BackupManager. (kfujino) + </fix> </changelog> </subsection> <subsection name="Other"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org