Hi Joerg,

Attached is a patch against cvs 2.0.5. It implements a caching directory generator the same way cocoon 2.1 does. An additional sitemap parameter "refreshDelay" is used to check the timestamps of the files periodically. If i should upload this into the patch queue on bugzilla let me know.

Hope This Helps (tm)
:)
Jorg

Joerg Heinicke wrote:

Hello Jorg,

the caching for the DirectoryGenerator was implemented on 13th of May in Cocoon 2.1: http://cvs.apache.org/viewcvs.cgi/cocoon-2.1/src/java/org/apache/cocoon/generation/DirectoryGenerator.java


Is it correct that you did it for Cocoon 2.0? Can you compare your caching with the one implemented in 2.1? And maybe provide a patch?


Thanks,

Joerg

Jorg Heymans wrote:

OK I understand the caching now a lot better. Anyone wanting to understand
how to implement his own caching should read


http://wiki.cocoondev.org/Wiki.jsp?page=WritingForCacheEfficiency
http://cocoon.apache.org/2.0/userdocs/concepts/caching.html

Note that in order for your serializer caching to work, the generator has to
implement cacheable as well because cocoon attempts to cache as far into the
pipeline as it can! If the start of the pipeline is already not cacheable
then the rest won't be either! This was the problem for me all along it
seems.


The often used file generator is cacheable, the directorygenerator I was
using is *not*. So I extended the existing DirectoryGenerator with a
CachingDirectoryGenerator implementing Cacheable. I implemented the
interface methods, reconfigured sitemap and voila my content is delivered
fully cached now in 100ms instead of 3s!!


Thanks again for your help Vladim, I hope this thread has helped other
people as well in understanding cocoon's caching mechanism.


Greetings Jorg


Index: org/apache/cocoon/generation/DirectoryGenerator.java
===================================================================
RCS file: 
/home/cvspublic/cocoon-2.0/src/java/org/apache/cocoon/generation/DirectoryGenerator.java,v
retrieving revision 1.3
diff -u -r1.3 DirectoryGenerator.java
--- org/apache/cocoon/generation/DirectoryGenerator.java        31 May 2003 01:22:05 
-0000      1.3
+++ org/apache/cocoon/generation/DirectoryGenerator.java        14 Jun 2003 22:31:18 
-0000
@@ -51,6 +51,8 @@
 package org.apache.cocoon.generation;
 
 import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.caching.CacheValidity;
+import org.apache.cocoon.caching.Cacheable;
 import org.apache.cocoon.ProcessingException;
 import org.apache.cocoon.ResourceNotFoundException;
 import org.apache.cocoon.environment.Source;
@@ -64,10 +66,13 @@
 import java.io.IOException;
 import java.net.URL;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 import java.util.Stack;
 
+
 /**
  * Generates an XML directory listing.
  * <p>
@@ -105,7 +110,8 @@
  *         (SMB GmbH) for Virbus AG
  * @version CVS $Id: DirectoryGenerator.java,v 1.3 2003/05/31 01:22:05 joerg Exp $
  */
-public class DirectoryGenerator extends ComposerGenerator  {
+public class DirectoryGenerator extends ComposerGenerator 
+  implements Cacheable {
   private static final String FILE = "file:";
 
     /** The URI of the namespace of this generator. */
@@ -122,7 +128,7 @@
     protected static final String FILENAME_ATTR_NAME    = "name";
     protected static final String LASTMOD_ATTR_NAME     = "lastModified";
     protected static final String DATE_ATTR_NAME        = "date";
-       protected static final String SIZE_ATTR_NAME        = "size";
+    protected static final String SIZE_ATTR_NAME        = "size";
 
     /*
      * Variables set per-request
@@ -139,6 +145,10 @@
 
     protected boolean isRequestedDirectory;
 
+    /** The delay between checks to the filesystem */
+    protected long refreshDelay;
+
+    protected DirValidity dirvalidity;
 
     /**
      * Set the request parameters. Must be called before the generate
@@ -169,6 +179,8 @@
 
         String rePattern = par.getParameter("root", null);
         try {
+            this.refreshDelay = par.getParameterAsLong("refreshDelay", 1L) * 1000L;
+
             getLogger().debug("root pattern: " + rePattern);
             this.rootRE = (rePattern == null)?null:new RE(rePattern);
 
@@ -320,6 +332,7 @@
     protected void startNode(String nodeName, File path)
     throws SAXException {
         setNodeAttributes(path);
+        dirvalidity.addFile(path);
         super.contentHandler.startElement(URI, nodeName, PREFIX+':'+nodeName, 
attributes);
     }
 
@@ -347,9 +360,9 @@
         attributes.addAttribute("", DATE_ATTR_NAME,
                     DATE_ATTR_NAME, "CDATA",
                     dateFormatter.format(new Date(lastModified)));
-               attributes.addAttribute("", SIZE_ATTR_NAME,
-                                       SIZE_ATTR_NAME, "CDATA",
-                                       Long.toString(path.length()));
+        attributes.addAttribute("", SIZE_ATTR_NAME,
+                    SIZE_ATTR_NAME, "CDATA",
+                    Long.toString(path.length()));
 
         if (this.isRequestedDirectory) {
             attributes.addAttribute("", "requested", "requested", "CDATA",
@@ -435,4 +448,78 @@
        this.excludeRE = null;
 
     }
+
+    /**
+     * @return the generator cache state ie key
+     */
+    public long generateKey() {
+
+        return 1;
+    }
+
+    /** 
+     * @return CacheValidity
+     *         the cachevalidity is a dirvalidity
+     *         which checks the timestamp of each file
+     */
+    public CacheValidity generateValidity() {
+
+        this.dirvalidity = new DirValidity(this.refreshDelay);
+        return this.dirvalidity;
+    }
+
+
+    /**
+     * Dirvalidity class providing timestamp checking on each file
+     *
+     */
+    public class DirValidity implements CacheValidity {
+
+        private long expiry;
+        private long delay;
+        List files = new ArrayList();
+        List fileDates = new ArrayList();
+
+        public DirValidity(long delay) {
+            expiry = System.currentTimeMillis() + delay;
+            this.delay = delay;
+        }
+
+        /* 
+         * @param cv the cachevalidity
+         * @return true if the cache is valid otherwise false
+         */
+        public boolean isValid(CacheValidity cv) {
+
+            if (System.currentTimeMillis() <= expiry)
+                return true;
+
+            expiry = System.currentTimeMillis() + delay;
+            int len = files.size();
+            for (int i = 0; i < len; i++) {
+                File f = (File) files.get(i);
+                if (!f.exists())
+                    return false; // File was removed
+
+                long oldDate = ((Long) fileDates.get(i)).longValue();
+                long newDate = f.lastModified();
+
+                if (oldDate != newDate)
+                    return false;
+            }
+
+            // All content is up to date : update the expiry date
+            expiry = System.currentTimeMillis() + delay;
+
+            return true;
+
+        }
+
+        public void addFile(File f) {
+            files.add(f);
+            fileDates.add(new Long(f.lastModified()));
+        }
+    }
+
+
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to