You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by ag...@apache.org on 2005/12/12 20:04:00 UTC

svn commit: r356331 - in /incubator/roller/trunk: metadata/xdoclet/ src/org/roller/presentation/filters/ web/WEB-INF/classes/

Author: agilliland
Date: Mon Dec 12 11:03:54 2005
New Revision: 356331

URL: http://svn.apache.org/viewcvs?rev=356331&view=rev
Log:
Adding Planet Cache.

- new cache specifically for Planet page and rss feed.
- modified old caches to not handle planet pages.
- updated filter mappings and properties


Added:
    incubator/roller/trunk/src/org/roller/presentation/filters/PlanetCacheFilter.java
Modified:
    incubator/roller/trunk/metadata/xdoclet/filter-mappings.xml
    incubator/roller/trunk/src/org/roller/presentation/filters/FeedCacheFilter.java
    incubator/roller/trunk/src/org/roller/presentation/filters/MainPageCacheFilter.java
    incubator/roller/trunk/web/WEB-INF/classes/roller.properties

Modified: incubator/roller/trunk/metadata/xdoclet/filter-mappings.xml
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/metadata/xdoclet/filter-mappings.xml?rev=356331&r1=356330&r2=356331&view=diff
==============================================================================
--- incubator/roller/trunk/metadata/xdoclet/filter-mappings.xml (original)
+++ incubator/roller/trunk/metadata/xdoclet/filter-mappings.xml Mon Dec 12 11:03:54 2005
@@ -125,29 +125,34 @@
     <filter-name>FeedCacheFilter</filter-name>
     <url-pattern>/flavor/*</url-pattern>
 </filter-mapping>
-<filter-mapping>
-    <filter-name>FeedCacheFilter</filter-name>
-    <url-pattern>/planetrss</url-pattern>
-</filter-mapping>
 
 
-<!-- Page Caching -->
+<!-- Weblog Page Caching -->
 <filter-mapping>
 	<filter-name>WeblogPageCacheFilter</filter-name>
 	<url-pattern>/page/*</url-pattern>
 </filter-mapping>
 
+
+<!-- Main Page Caching -->
 <filter-mapping>
 	<filter-name>MainPageCacheFilter</filter-name>
 	<url-pattern>/main.do</url-pattern>
 	<dispatcher>REQUEST</dispatcher>
 	<dispatcher>FORWARD</dispatcher>
 </filter-mapping>
+
+
+<!-- Planet Roller Caching -->
 <filter-mapping>
-	<filter-name>MainPageCacheFilter</filter-name>
+	<filter-name>PlanetCacheFilter</filter-name>
 	<url-pattern>/planet.do</url-pattern>
 	<dispatcher>REQUEST</dispatcher>
 	<dispatcher>FORWARD</dispatcher>
+</filter-mapping>
+<filter-mapping>
+    <filter-name>PlanetCacheFilter</filter-name>
+    <url-pattern>/planetrss</url-pattern>
 </filter-mapping>
 
 

Modified: incubator/roller/trunk/src/org/roller/presentation/filters/FeedCacheFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/FeedCacheFilter.java?rev=356331&r1=356330&r2=356331&view=diff
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/FeedCacheFilter.java (original)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/FeedCacheFilter.java Mon Dec 12 11:03:54 2005
@@ -44,7 +44,7 @@
 /**
  * A filter used for caching fully rendered xml feeds.
  *
- * This filter should only be applied to /rss/*, /atom/*, /flavor/*, /planetrss
+ * This filter should only be applied to /rss/*, /atom/*, /flavor/*
  *
  * @web.filter name="FeedCacheFilter"
  *
@@ -152,7 +152,6 @@
      * examples ...
      *
      * main/rss/en
-     * planet/rss/en
      * weblog/foo/rss/MyCategory/en
      * weblog/foo/atom/en/excerpts
      *

Modified: incubator/roller/trunk/src/org/roller/presentation/filters/MainPageCacheFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/MainPageCacheFilter.java?rev=356331&r1=356330&r2=356331&view=diff
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/MainPageCacheFilter.java (original)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/MainPageCacheFilter.java Mon Dec 12 11:03:54 2005
@@ -77,8 +77,6 @@
         String servlet = request.getServletPath();
         if(servlet.equals("/main.do")) {
             key = "main/page";
-        } else if(servlet.equals("/planet.do")) {
-            key = "planet/page";
         } else {
             // not a main page request
             mLogger.warn("not a main page "+servlet);

Added: incubator/roller/trunk/src/org/roller/presentation/filters/PlanetCacheFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/PlanetCacheFilter.java?rev=356331&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/PlanetCacheFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/PlanetCacheFilter.java Mon Dec 12 11:03:54 2005
@@ -0,0 +1,350 @@
+/*
+ * PlanetCacheFilter.java
+ *
+ * Created on December 12, 2005, 10:03 AM
+ */
+
+package org.roller.presentation.filters;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.config.RollerConfig;
+import org.roller.pojos.BookmarkData;
+import org.roller.pojos.CommentData;
+import org.roller.pojos.FolderData;
+import org.roller.pojos.RefererData;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WeblogCategoryData;
+import org.roller.pojos.WeblogEntryData;
+import org.roller.pojos.WeblogTemplate;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.LanguageUtil;
+import org.roller.presentation.PlanetRequest;
+import org.roller.presentation.cache.Cache;
+import org.roller.presentation.cache.CacheHandler;
+import org.roller.presentation.cache.CacheManager;
+import org.roller.presentation.util.CacheHttpServletResponseWrapper;
+import org.roller.presentation.util.ResponseContent;
+
+
+/**
+ * A cache filter for Planet Roller items ... /planet.do, /planetrss
+ *
+ * @web.filter name="PlanetCacheFilter"
+ *
+ * @author Allen Gilliland
+ */
+public class PlanetCacheFilter implements Filter, CacheHandler {
+    
+    private static Log mLogger = LogFactory.getLog(PlanetCacheFilter.class);
+    
+    private boolean excludeOwnerPages = false;
+    private Cache mCache = null;
+    
+    // for metrics
+    private double hits = 0;
+    private double misses = 0;
+    private double skips = 0;
+    private Date startTime = new Date();
+    
+    
+    /**
+     * Process filter.
+     */
+    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
+            throws IOException, ServletException {
+        
+        mLogger.debug("entering");
+        
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) res;
+        
+        PlanetRequest planetRequest = null;
+        try {
+            planetRequest = new PlanetRequest(request);
+        } catch(Exception e) {
+            // some kind of error parsing the request
+            mLogger.error("error creating planet request", e);
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+        
+        String key = "planetCache:"+this.generateKey(planetRequest);
+        
+        try {
+            ResponseContent respContent = null;
+            if(!this.excludeOwnerPages || !planetRequest.isLoggedIn()) {
+                respContent = (ResponseContent) this.mCache.get(key);
+            }
+            
+            if(respContent == null) {
+
+                mLogger.debug("MISS "+key);
+                this.misses++;
+                
+                CacheHttpServletResponseWrapper cacheResponse =
+                        new CacheHttpServletResponseWrapper(response);
+                
+                chain.doFilter(request, cacheResponse);
+                
+                cacheResponse.flushBuffer();
+                
+                // only cache if we didn't get an exception
+                if (request.getAttribute("DisplayException") == null) {
+                    ResponseContent rc = cacheResponse.getContent();
+                    
+                    // only cache if this is not a logged in user?
+                    if(!this.excludeOwnerPages || !planetRequest.isLoggedIn()) {
+                        this.mCache.put(key, rc);
+                    } else {
+                        mLogger.debug("SKIPPED "+key);
+                        this.skips++;
+                    }
+                } else {
+                    // it is expected that whoever caught this display exception
+                    // is the one who reported it to the logs
+                    mLogger.debug("Display exception "+key);
+                }
+                
+            } else {
+                
+                mLogger.debug("HIT "+key);
+                this.hits++;
+                
+                respContent.writeTo(response);
+            }
+            
+        } catch(Exception ex) {
+            
+            if(ex.getMessage().indexOf("ClientAbort") != -1) {
+                // ClientAbortException ... ignored
+                mLogger.debug(ex.getMessage());
+                
+            } else if(ex.getMessage().indexOf("SocketException") != -1) {
+                // SocketException ... ignored
+                mLogger.debug(ex.getMessage());
+                
+            } else {
+                mLogger.error("Unexpected exception rendering page "+key, ex);
+            }
+            
+            // gotta send something to the client
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        }
+        
+        mLogger.debug("exiting");
+    }
+    
+    
+    /**
+     * Generate a cache key from a parsed planet request.
+     * This generates a key of the form ...
+     *
+     * <context>/<type>/<language>[/user]
+     *   or
+     * <context>/<type>[/flavor]/<language>[/excerpts]
+     *
+     *
+     * examples ...
+     *
+     * planet/page/en
+     * planet/feed/rss/en/excerpts
+     *
+     */
+    private String generateKey(PlanetRequest planetRequest) {
+        
+        StringBuffer key = new StringBuffer();
+        key.append(planetRequest.getContext());
+        key.append("/");
+        key.append(planetRequest.getType());
+        
+        if(planetRequest.getFlavor() != null) {
+            key.append("/").append(planetRequest.getFlavor());
+        }
+        
+        // add language
+        key.append("/").append(planetRequest.getLanguage());
+        
+        if(planetRequest.getFlavor() != null) {
+            // add excerpts
+            if(planetRequest.isExcerpts()) {
+                key.append("/excerpts");
+            }
+        } else {
+            // add login state
+            if(planetRequest.getAuthenticUser() != null) {
+                key.append("/user=").append(planetRequest.getAuthenticUser());
+            }
+        }
+        
+        return key.toString();
+    }
+    
+    
+    /**
+     * A weblog entry has changed.
+     */
+    public void invalidate(WeblogEntryData entry) {
+        // ignored
+    }
+    
+    
+    /**
+     * A weblog has changed.
+     */
+    public void invalidate(WebsiteData website) {
+        // ignored
+    }
+    
+    
+    /**
+     * A bookmark has changed.
+     */
+    public void invalidate(BookmarkData bookmark) {
+        // ignored
+    }
+    
+    
+    /**
+     * A folder has changed.
+     */
+    public void invalidate(FolderData folder) {
+        // ignored
+    }
+    
+    
+    /**
+     * A comment has changed.
+     */
+    public void invalidate(CommentData comment) {
+        // ignored
+    }
+    
+    
+    /**
+     * A referer has changed.
+     */
+    public void invalidate(RefererData referer) {
+        // ignored
+    }
+    
+    
+    /**
+     * A user profile has changed.
+     */
+    public void invalidate(UserData user) {
+        // ignored
+    }
+    
+    
+    /**
+     * A category has changed.
+     */
+    public void invalidate(WeblogCategoryData category) {
+        // ignored
+    }
+    
+    
+    /**
+     * A weblog template has changed.
+     */
+    public void invalidate(WeblogTemplate template) {
+        // ignored
+    }
+    
+    
+    /**
+     * Clear the entire cache.
+     */
+    public void clear() {
+        mLogger.info("Clearing cache");
+        this.mCache.clear();
+        this.startTime = new Date();
+        this.hits = 0;
+        this.misses = 0;
+        this.skips = 0;
+    }
+    
+    
+    public Map getStats() {
+        
+        Map stats = new HashMap();
+        stats.put("cacheType", this.mCache.getClass().getName());
+        stats.put("startTime", this.startTime);
+        stats.put("hits", new Double(this.hits));
+        stats.put("misses", new Double(this.misses));
+        stats.put("skips", new Double(this.skips));
+        
+        // calculate efficiency
+        if(misses > 0) {
+            double efficiency = hits / (misses + hits);
+            stats.put("efficiency", new Double(efficiency * 100));
+        }
+        
+        return stats;
+    }
+    
+    
+    /**
+     * Destroy method for this filter
+     */
+    public void destroy() {
+    }
+    
+    
+    /**
+     * Init method for this filter
+     */
+    public void init(FilterConfig filterConfig) {
+        
+        mLogger.info("Initializing planet cache");
+        
+        String factory = RollerConfig.getProperty("cache.planet.factory");
+        String size = RollerConfig.getProperty("cache.planet.size");
+        String timeout = RollerConfig.getProperty("cache.planet.timeout");
+        this.excludeOwnerPages = 
+                RollerConfig.getBooleanProperty("cache.planet.excludeOwnerEditPages");
+        
+        int cacheSize = 20;
+        try {
+            cacheSize = Integer.parseInt(size);
+        } catch (Exception e) {
+            mLogger.warn("Invalid cache size ["+size+"], using default");
+        }
+        
+        long cacheTimeout = 30 * 60;
+        try {
+            cacheTimeout = Long.parseLong(timeout);
+        } catch (Exception e) {
+            mLogger.warn("Invalid cache timeout ["+timeout+
+                    "], using default");
+        }
+        
+        
+        Map props = new HashMap();
+        props.put("timeout", ""+cacheTimeout);
+        props.put("size", ""+cacheSize);
+        
+        if(factory != null && factory.trim().length() > 0)
+            props.put("cache.factory", factory);
+        
+        mLogger.info(props);
+        
+        mCache = CacheManager.constructCache(this, props);
+    }
+    
+}

Modified: incubator/roller/trunk/web/WEB-INF/classes/roller.properties
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/web/WEB-INF/classes/roller.properties?rev=356331&r1=356330&r2=356331&view=diff
==============================================================================
--- incubator/roller/trunk/web/WEB-INF/classes/roller.properties (original)
+++ incubator/roller/trunk/web/WEB-INF/classes/roller.properties Mon Dec 12 11:03:54 2005
@@ -64,13 +64,13 @@
 cache.factory.classname=org.roller.presentation.cache.ExpiringLRUCacheFactoryImpl
 cache.customHandlers=
 
-
 # Main/Planet page cache (this is low on purpose)
 cache.mainpage.size=10
 cache.mainpage.timeout=1800
 # set "true" to NOT cache the custom pages for users who are logged in
 cache.mainpage.excludeOwnerEditPages=false
 
+
 # Weblog page cache (all the weblog content)
 cache.weblogpage.size=400
 cache.weblogpage.timeout=3600
@@ -91,6 +91,13 @@
 # you want a reasonable size, like weblogs * 2, with long timeouts
 cache.feed.ifmodified.size=200
 cache.feed.ifmodified.timeout=14400
+
+
+# Planet cache (planet page and rss feed)
+cache.planet.size=10
+cache.planet.timeout=1800
+# set "true" to NOT cache the custom pages for users who are logged in
+cache.planet.excludeOwnerEditPages=false
 
 #----------------------------------
 # Secure login configs