Author: agilliland
Date: Sat Feb 18 11:45:57 2006
New Revision: 378765
URL: http://svn.apache.org/viewcvs?rev=378765&view=rev
Log:
fix for ROL-902, publish to future not working.
this fix starts a single thread which will peer into the future at timed
intervals to build a list of future posted entries that need cache expirations.
Added:
incubator/roller/trunk/src/org/roller/presentation/cache/FuturePostingsInvalidationJob.java
Modified:
incubator/roller/trunk/src/org/roller/presentation/RollerContext.java
incubator/roller/trunk/src/org/roller/presentation/cache/CacheManager.java
incubator/roller/trunk/web/WEB-INF/classes/roller.properties
Modified: incubator/roller/trunk/src/org/roller/presentation/RollerContext.java
URL:
http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/RollerContext.java?rev=378765&r1=378764&r2=378765&view=diff
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/RollerContext.java
(original)
+++ incubator/roller/trunk/src/org/roller/presentation/RollerContext.java Sat
Feb 18 11:45:57 2006
@@ -52,6 +52,7 @@
import org.springframework.web.context.support.WebApplicationContextUtils;
import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
+import org.roller.presentation.cache.CacheManager;
/**
@@ -104,6 +105,9 @@
/** Responds to app-destroy by saving the indexManager's information */
public void contextDestroyed(ServletContextEvent sce) {
RollerFactory.getRoller().shutdown();
+
+ // do we need a more generic mechanism for presentation layer shutdown?
+ CacheManager.shutdown();
}
Modified:
incubator/roller/trunk/src/org/roller/presentation/cache/CacheManager.java
URL:
http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/cache/CacheManager.java?rev=378765&r1=378764&r2=378765&view=diff
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/cache/CacheManager.java
(original)
+++ incubator/roller/trunk/src/org/roller/presentation/cache/CacheManager.java
Sat Feb 18 11:45:57 2006
@@ -15,6 +15,8 @@
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.roller.business.runnable.ContinuousWorkerThread;
+import org.roller.business.runnable.Job;
import org.roller.config.RollerConfig;
import org.roller.pojos.BookmarkData;
import org.roller.pojos.CommentData;
@@ -58,6 +60,8 @@
// a list of all cache handlers who have obtained a cache
private static Set cacheHandlers = new HashSet();
+ private static ContinuousWorkerThread futureInvalidationsThread = null;
+
static {
// lookup what cache factory we want to use
@@ -90,7 +94,7 @@
// setup our cache for expiration dates
lastExpiredCache = new Hashtable();
- // finally, add custom handlers
+ // add custom handlers
String customHandlers =
RollerConfig.getProperty("cache.customHandlers");
if(customHandlers != null && customHandlers.trim().length() > 0) {
@@ -112,6 +116,32 @@
}
}
+ // determine future invalidations peering window
+ Integer peerTime = new Integer(5);
+ String peerTimeString =
RollerConfig.getProperty("cache.futureInvalidations.peerTime");
+ try {
+ peerTime = new Integer(peerTimeString);
+ } catch(NumberFormatException nfe) {
+ // bad input from config file, default already set
+ }
+
+ // thread time is always 10 secs less than peer time to make sure
+ // there is a little overlap so we don't miss any entries
+ // this means every XX seconds we peer XX + 10 seconds into the future
+ int threadTime = (peerTime.intValue() * 60 * 1000) - (10 * 1000);
+
+ // start up future invalidations job, running continuously
+ futureInvalidationsThread = new ContinuousWorkerThread("future
invalidations thread", threadTime);
+ Job futureInvalidationsJob = new FuturePostingsInvalidationJob();
+
+ // inputs
+ Map inputs = new HashMap();
+ inputs.put("peerTime", peerTime);
+ futureInvalidationsJob.input(inputs);
+
+ // set job and start it
+ futureInvalidationsThread.setJob(futureInvalidationsJob);
+ futureInvalidationsThread.start();
}
@@ -390,6 +420,18 @@
}
return allStats;
+ }
+
+
+ /**
+ * Place to do any cleanup tasks for cache system.
+ */
+ public static void shutdown() {
+
+ // stop our future invalidations thread
+ if(futureInvalidationsThread != null) {
+ futureInvalidationsThread.interrupt();
+ }
}
}
Added:
incubator/roller/trunk/src/org/roller/presentation/cache/FuturePostingsInvalidationJob.java
URL:
http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/cache/FuturePostingsInvalidationJob.java?rev=378765&view=auto
==============================================================================
---
incubator/roller/trunk/src/org/roller/presentation/cache/FuturePostingsInvalidationJob.java
(added)
+++
incubator/roller/trunk/src/org/roller/presentation/cache/FuturePostingsInvalidationJob.java
Sat Feb 18 11:45:57 2006
@@ -0,0 +1,119 @@
+/*
+ * FuturePostingsInvalidationJob.java
+ *
+ * Created on February 14, 2006, 5:48 PM
+ */
+
+package org.roller.presentation.cache;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.business.referrers.ReferrerProcessingJob;
+import org.roller.business.runnable.*;
+import org.roller.model.RollerFactory;
+import org.roller.model.WeblogManager;
+import org.roller.pojos.WeblogEntryData;
+
+
+/**
+ * Trigger cache invalidations for entries published into the future.
+ *
+ * This job is meant to be run at timed intervals, it will not do any
+ * good to run this job only a single time.
+ *
+ * We do things in a somewhat counterintuitive manner, but it makes things
+ * easier on us from an operational point of view. We start by looking up
+ * all entries published between now and some time XX mins in the future. We
+ * then save that list and when XX mins has passed we invalidate the list and
+ * query for entries published in the next XX mins.
+ *
+ * Basically we are building a short term list of future published entries
+ * and expiring them once our wait period is over. This prevents us from
+ * having to somehow determine which entries published in the last XX mins
+ * had previously been published into the future.
+ *
+ * @author Allen Gilliland
+ */
+public class FuturePostingsInvalidationJob implements Job {
+
+ private static Log mLogger =
LogFactory.getLog(FuturePostingsInvalidationJob.class);
+
+ // inputs from the user
+ private Map inputs = null;
+
+ // the list of entries we expire at the start of the next run
+ private List nextExpirations = null;
+
+ // how far into the future we will look ahead, in minutes
+ int peerTime = 5;
+
+ public void execute() {
+
+ mLogger.debug("starting");
+
+ // notify the cache manager of an invalidation
+ if(nextExpirations != null) {
+ WeblogEntryData entry = null;
+ Iterator entries = nextExpirations.iterator();
+ while(entries.hasNext()) {
+ entry = (WeblogEntryData) entries.next();
+
+ mLogger.debug("expiring "+entry.getAnchor());
+
+ CacheManager.invalidate(entry);
+ }
+ }
+
+ // look for postings from current time to current time plus XX mins
+ List expiringEntries = null;
+ try {
+ WeblogManager mgr = RollerFactory.getRoller().getWeblogManager();
+
+ // current time
+ Date start = new Date();
+
+ // XX mins in the future
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(start);
+ cal.add(Calendar.MINUTE, this.peerTime);
+ Date end = cal.getTime();
+
+ mLogger.debug("looking up entries between "+start+" and "+end);
+
+ // get all published entries between start and end date
+ expiringEntries = mgr.getWeblogEntries(null, start, end, null,
+ null, WeblogEntryData.PUBLISHED, null);
+
+ this.nextExpirations = expiringEntries;
+
+ } catch(Exception e) {
+ mLogger.error(e);
+ }
+
+ mLogger.debug("finished");
+ }
+
+
+ public Map output() {
+ return null;
+ }
+
+
+ public void input(Map input) {
+ this.inputs = input;
+
+ // extract peer time if possible
+ Integer pTime = (Integer) this.inputs.get("peerTime");
+ if(pTime != null) {
+ this.peerTime = pTime.intValue();
+ }
+
+ mLogger.info("Peeking "+this.peerTime+" minutes into the future each
pass");
+ }
+
+}
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=378765&r1=378764&r2=378765&view=diff
==============================================================================
--- incubator/roller/trunk/web/WEB-INF/classes/roller.properties (original)
+++ incubator/roller/trunk/web/WEB-INF/classes/roller.properties Sat Feb 18
11:45:57 2006
@@ -76,7 +76,12 @@
cache.defaultFactory=org.roller.presentation.cache.ExpiringLRUCacheFactoryImpl
cache.customHandlers=
-# Main/Planet page cache (this is low on purpose)
+# This sets how many minutes into the future we look to prepare
+# entries posted into the future which need to be invalidated from the cache.
+# It is very unlikely that this should ever need to be changed
+cache.futureInvalidations.peerTime=3
+
+# Main 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