You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2006/03/10 23:17:23 UTC

svn commit: r384937 - in /tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis: Diffable.java LazyReplicatedMap.java ReplicatedMapEntry.java

Author: fhanik
Date: Fri Mar 10 14:17:21 2006
New Revision: 384937

URL: http://svn.apache.org/viewcvs?rev=384937&view=rev
Log:
Implemented map scan to replicate out changes

Added:
    tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java
      - copied, changed from r384918, tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/Diffable.java
Removed:
    tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/Diffable.java
Modified:
    tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/LazyReplicatedMap.java

Modified: tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/LazyReplicatedMap.java
URL: http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/LazyReplicatedMap.java?rev=384937&r1=384936&r2=384937&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/LazyReplicatedMap.java (original)
+++ tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/LazyReplicatedMap.java Fri Mar 10 14:17:21 2006
@@ -112,6 +112,63 @@
         this.stateTransferred = false;
     }
     
+    /**
+     * Replicates any changes to the object since the last time
+     * The object has to be primary, ie, if the object is a proxy or a backup, it will not be replicated<br>
+     * @param complete - if set to true, the object is replicated to its backup
+     * if set to false, only objects that implement ReplicatedMapEntry and the isDirty() returns true will
+     * be replicated
+     */
+    public void replicate(Object key, boolean complete) {
+        MapEntry entry = (MapEntry) super.get(key);
+        if (entry!=null && entry.isPrimary() ) {
+            Object value = entry.getValue();
+            boolean repl = complete || ((value instanceof ReplicatedMapEntry) && ((ReplicatedMapEntry)value).isDirty());
+            if (!repl) return;
+
+            boolean diff = ((value instanceof ReplicatedMapEntry) && ((ReplicatedMapEntry)value).isDiffable());
+            MapMessage msg = null;
+            if ( diff ) {
+                try {
+                    msg = new MapMessage(mapContextName, MapMessage.MSG_BACKUP,
+                                         true, (Serializable) entry.getKey(), null,
+                                         ( (ReplicatedMapEntry) entry.getValue()).getDiff(),
+                                         entry.getBackupNode());
+                }catch (IOException x ) {
+                    log.error("Unable to diff object. Will replicate the entire object instead.",x);
+                }
+            }
+            if ( msg == null ) {
+                msg = new MapMessage(mapContextName, MapMessage.MSG_BACKUP,
+                                     false, (Serializable) entry.getKey(), 
+                                     (Serializable)entry.getValue(),
+                                     null,entry.getBackupNode());
+
+            }
+            try {
+                channel.send(new Member[] {entry.getBackupNode()}, msg);
+            } catch ( ChannelException x ) {
+                log.error("Unable to replicate data.",x);
+            }
+        }//end if
+
+    }
+    
+    /**
+     * This can be invoked by a periodic thread to replicate out any changes.
+     * For maps that don't store objects that implement ReplicatedMapEntry, this
+     * method should be used infrequently to avoid large amounts of data transfer
+     * @param complete boolean
+     */
+    public void replicate(boolean complete) {
+        Iterator i = super.entrySet().iterator();
+        while (i.hasNext()) {
+            Map.Entry e = (Map.Entry) i.next();
+            replicate(e.getKey(),complete);
+        } //while
+
+    }
+    
 //------------------------------------------------------------------------------    
 //              GROUP COM INTERFACES
 //------------------------------------------------------------------------------   
@@ -211,22 +268,22 @@
                 entry.setBackupNode(mapmsg.getBackupNode());
                 super.put(entry.getKey(), entry);
             } else {
-                if ( mapmsg.isDiff() ) {
-                    if ( entry.getValue() instanceof Diffable ) {
-                        Diffable diff = (Diffable)entry.getValue();
+                if ( entry.getValue() instanceof ReplicatedMapEntry ) {
+                    ReplicatedMapEntry diff = (ReplicatedMapEntry)entry.getValue();
+                    if ( mapmsg.isDiff() ) {
                         try {
                             diff.applyDiff(mapmsg.getDiffValue(), 0, mapmsg.getDiffValue().length);
                         }catch ( IOException x ) {
                             log.error("Unable to apply diff to key:"+entry.getKey(),x);
                         }
                     } else {
-                        log.warn("Received a DIFF replication, but object["+entry.getValue()+"] does not implement Diffable");
-                    }
+                        entry.setValue(mapmsg.getValue());
+                    }//end if
                 } else {
                     entry.setValue(mapmsg.getValue());
-                }
-            }
-        }
+                }//end if
+            }//end if
+        }//end if
         
     }
     
@@ -402,6 +459,12 @@
         throw new UnsupportedOperationException("This operation is not valid on a replicated map");
     }
     
+    /**
+     * Returns the entire contents of the map
+     * Map.Entry.getValue() will return a LazyReplicatedMap.MapEntry object containing all the information 
+     * about the object.
+     * @return Set
+     */
     public Set entrySetFull() {
         return super.entrySet();
     }
@@ -504,7 +567,7 @@
         }
 
         public boolean isDiffable() {
-            return (value instanceof Diffable);
+            return (value instanceof ReplicatedMapEntry);
         }
         
         public void setBackupNode(Member node) {
@@ -532,7 +595,7 @@
 
         public byte[] getDiff() throws IOException {
             if ( isDiffable() ) {
-                return ((Diffable)value).getDiff();
+                return ((ReplicatedMapEntry)value).getDiff();
             } else {
                 return getData();
             }
@@ -566,7 +629,7 @@
          */
         public void apply(byte[] data, int offset, int length, boolean diff) throws IOException, ClassNotFoundException {
             if ( isDiffable() && diff ) {
-                ((Diffable)value).applyDiff(data,offset,length);
+                ((ReplicatedMapEntry)value).applyDiff(data,offset,length);
             } else if ( length == 0 ) {
                 value = null;
                 proxy = true;

Copied: tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java (from r384918, tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/Diffable.java)
URL: http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java?p2=tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java&p1=tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/Diffable.java&r1=384918&r2=384937&rev=384937&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/Diffable.java (original)
+++ tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/tipis/ReplicatedMapEntry.java Fri Mar 10 14:17:21 2006
@@ -20,16 +20,44 @@
 
 /**
  * 
- *
+ * For smarter replication, an object can implement this interface to replicate diffs
  * @author Filip Hanik
  * @version 1.0
  */
-public interface Diffable extends Serializable {
+public interface ReplicatedMapEntry extends Serializable {
     
+    /**
+     * Has the object changed since last replication
+     * and is not in a locked state
+     * @return boolean
+     */
+    public boolean isDirty();
+    
+    public boolean setDirty(boolean dirty);
+    
+    /**
+     * If this returns true, the map will extract the diff using getDiff()
+     * Otherwise it will serialize the entire object.
+     * @return boolean
+     */
+    public boolean isDiffable();
+    
+    /**
+     * Returns a diff and sets the dirty map to false
+     * @return byte[]
+     * @throws IOException
+     */
     public byte[] getDiff() throws IOException;
     
+    
+    /**
+     * Applies a diff to an existing object.
+     * @param diff byte[]
+     * @param offset int
+     * @param length int
+     * @throws IOException
+     */
     public void applyDiff(byte[] diff, int offset, int length) throws IOException;
     
-    public boolean hasDiff();
     
 }



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