You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by kf...@apache.org on 2012/04/17 08:06:52 UTC

svn commit: r1326938 - in /tomcat/trunk/java/org/apache/catalina: ha/session/DeltaSession.java tribes/tipis/AbstractReplicatedMap.java tribes/tipis/ReplicatedMapEntry.java

Author: kfujino
Date: Tue Apr 17 06:06:51 2012
New Revision: 1326938

URL: http://svn.apache.org/viewvc?rev=1326938&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/trunk/java/org/apache/catalina/ha/session/DeltaSession.java
    tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java
    tomcat/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java

Modified: tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java?rev=1326938&r1=1326937&r2=1326938&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java (original)
+++ tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java Tue Apr 17 06:06:51 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/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java?rev=1326938&r1=1326937&r2=1326938&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java (original)
+++ tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java Tue Apr 17 06:06:51 2012
@@ -408,8 +408,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() )
@@ -418,9 +420,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();
@@ -438,6 +440,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,
@@ -448,6 +456,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) {
@@ -677,6 +688,17 @@ public abstract class AbstractReplicated
             } //end if
             innerMap.put(entry.getKey(), entry);
         } //end if
+
+        if (mapmsg.getMsgType() == MapMessage.MSG_ACCESS) {
+            MapEntry<K, V> entry = innerMap.get(mapmsg.getKey());
+            if (entry != null) {
+                entry.setBackupNodes(mapmsg.getBackupNodes());
+                entry.setPrimary(mapmsg.getPrimary());
+                if (entry.getValue() instanceof ReplicatedMapEntry) {
+                    ((ReplicatedMapEntry) entry.getValue()).accessEntry();
+                }
+            }
+        }
     }
 
     @Override
@@ -1287,6 +1309,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;
@@ -1324,6 +1347,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/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java?rev=1326938&r1=1326937&r2=1326938&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java (original)
+++ tomcat/trunk/java/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java Tue Apr 17 06:06:51 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



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org