You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by cu...@apache.org on 2010/02/25 01:11:33 UTC
svn commit: r916052 - in /openjpa/trunk:
openjpa-kernel/src/main/java/org/apache/openjpa/datacache/
openjpa-persistence-jdbc/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/
openjpa-project/src/doc/manual/
Author: curtisr7
Date: Thu Feb 25 00:11:33 2010
New Revision: 916052
URL: http://svn.apache.org/viewvc?rev=916052&view=rev
Log:
OPENJPA-1531: Adding support for a interval style syntax in the openjpa.DataCache.EvictionSchedule property. Added code changes, test case, and doc.
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java
openjpa/trunk/openjpa-persistence-jdbc/pom.xml
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java
openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java?rev=916052&r1=916051&r2=916052&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java Thu Feb 25 00:11:33 2010
@@ -21,19 +21,23 @@
import java.security.AccessController;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
-import java.util.concurrent.ConcurrentHashMap;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.UserException;
+
import serp.util.Strings;
/**
@@ -54,7 +58,7 @@
private Map _caches = new ConcurrentHashMap();
private boolean _stop = false;
- private int _interval = 2;
+ private int _interval = 1;
private Log _log;
private Thread _thread;
@@ -63,14 +67,14 @@
}
/**
- * The interval time in minutes between cache checks. Defaults to 2.
+ * The interval time in minutes between cache checks. Defaults to 1.
*/
public int getInterval() {
return _interval;
}
/**
- * The interval time in minutes between cache checks. Defaults to 2.
+ * The interval time in minutes between cache checks. Defaults to 1.
*/
public void setInterval(int interval) {
_interval = interval;
@@ -181,19 +185,46 @@
final int[] min;
public Schedule(String date) {
- StringTokenizer token = new StringTokenizer(date, " \t");
- if (token.countTokens() != 5)
- throw new UserException(_loc.get("bad-count", date)).
- setFatal(true);
- try {
- min = parse(token.nextToken(), 0, 60);
- hour = parse(token.nextToken(), 0, 24);
- dayOfMonth = parse(token.nextToken(), 1, 31);
- month = parse(token.nextToken(), 1, 13);
- dayOfWeek = parse(token.nextToken(), 1, 8);
- } catch (Throwable t) {
- throw new UserException(_loc.get("bad-schedule", date), t).
- setFatal(true);
+ int[] tmin = null;
+ if (date.startsWith("+")) {
+ Calendar cal = Calendar.getInstance();
+ int interval = Integer.parseInt(date.substring(1));
+ int currMin = cal.get(Calendar.MINUTE);
+
+ tmin = new int[60/interval];
+ for(int i = 0; i<tmin.length;i++){
+ int temp;
+ if(i==0){
+ temp=currMin+interval;
+ }else{
+ temp=tmin[i-1]+interval;
+ }
+ if(temp >= 60 ){
+ temp -= 60;
+ }
+ tmin[i]=temp;
+ }
+ Arrays.sort(tmin);
+
+ min = tmin;
+ hour = WILDCARD;
+ dayOfMonth = WILDCARD;
+ month = WILDCARD;
+ dayOfWeek = WILDCARD;
+ }else{
+
+ StringTokenizer token = new StringTokenizer(date, " \t");
+ if (token.countTokens() != 5)
+ throw new UserException(_loc.get("bad-count", date)).setFatal(true);
+ try {
+ min = parse(token.nextToken(), 0, 60);
+ hour = parse(token.nextToken(), 0, 24);
+ dayOfMonth = parse(token.nextToken(), 1, 31);
+ month = parse(token.nextToken(), 1, 13);
+ dayOfWeek = parse(token.nextToken(), 1, 8);
+ } catch (Throwable t) {
+ throw new UserException(_loc.get("bad-schedule", date), t).setFatal(true);
+ }
}
}
Modified: openjpa/trunk/openjpa-persistence-jdbc/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/pom.xml?rev=916052&r1=916051&r2=916052&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/pom.xml (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/pom.xml Thu Feb 25 00:11:33 2010
@@ -809,7 +809,6 @@
<exclude>org/apache/openjpa/persistence/conf/TestOpenJPAConfiguration.java</exclude>
<exclude>org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java</exclude>
<exclude>org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java</exclude>
- <exclude>org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java</exclude>
<exclude>org/apache/openjpa/persistence/datacache/TestDistributedKodoDataCache.java</exclude>
<exclude>org/apache/openjpa/persistence/datacache/TestFlushDataCache.java</exclude>
<exclude>org/apache/openjpa/persistence/datacache/TestJPQL2Queries.java</exclude>
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java?rev=916052&r1=916051&r2=916052&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java Thu Feb 25 00:11:33 2010
@@ -20,33 +20,17 @@
import java.util.Calendar;
import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.openjpa.persistence.datacache.common.apps.ScheduledEviction;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.datacache.DataCache;
-import org.apache.openjpa.datacache.DataCacheScheduler;
import org.apache.openjpa.datacache.ConcurrentDataCache;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.util.Id;
-
-public class TestDataCacheScheduler
- extends AbstractTestCase {
-
- private static final String MINUTES = getMinutes();
+import org.apache.openjpa.datacache.DataCacheScheduler;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.datacache.common.apps.ScheduledEviction;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
- public TestDataCacheScheduler(String str) {
- super(str, "datacachecactusapp");
- }
+public class TestDataCacheScheduler extends SingleEMTestCase {
- private static String getMinutes() {
+ private static String getMinutesString() {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < 60; i++) {
if (i % 2 == 0)
@@ -56,172 +40,86 @@
}
public void setUp() {
- deleteAll(ScheduledEviction.class);
- }
-
- public void testRuntime()
- throws Exception {
- String sched = MINUTES + " * * * *";
- Map propsMap = new HashMap();
- propsMap.put("openjpa.DataCache", "true(EvictionSchedule=\"" + sched
- + "\")");
- propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
- propsMap.put("openjpa.FlushBeforeQueries", "true");
- propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
- OpenJPAEntityManagerFactory emf =
- (OpenJPAEntityManagerFactory) getEmf(propsMap);
-
- ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf))
- .getConfiguration().getDataCacheManagerInstance()
- .getDataCacheScheduler().setInterval(1);
- DataCache cache = JPAFacadeHelper.getMetaData(emf,
- ScheduledEviction.class).getDataCache();
-
- OpenJPAEntityManager em = (OpenJPAEntityManager) emf
- .createEntityManager();
- startTx(em);
- ScheduledEviction pc = new ScheduledEviction("Foo");
- em.persist(pc);
- Object oid = em.getObjectId(pc);
- Object oidwithclass = new Id(ScheduledEviction.class, oid.toString());
- endTx(em);
- endEm(em);
-
- cache.clear();// clear and wait until next run.
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- if (cal.get(Calendar.MINUTE) % 2 == 0)
- Thread.currentThread().sleep
- ((60 - cal.get(Calendar.SECOND)) * 1000);
- cal.setTime(new Date());
- assertTrue(cal.get(Calendar.MINUTE) % 2 == 1);
- em = (OpenJPAEntityManager) emf.createEntityManager();
- em.find(ScheduledEviction.class, oid);
- endEm(em);
- assertTrue(cache.contains(oidwithclass));
-
- Thread.currentThread().sleep(130 * 1000);
- assertFalse(cache.contains(oidwithclass));
- emf.close();
+ setUp(ScheduledEviction.class, CLEAR_TABLES
+ );
}
- /**
- * too slow ! *
- */
- //FIXME Seetha Sep 26,2006
- /*public void XXXtestRunnable()
- throws Exception {
- KodoPersistenceManager pm = getPM();
- OpenJPAConfiguration conf = pm.getConfiguration();
+ public void testBasic() throws Exception {
+ OpenJPAConfiguration conf = ((OpenJPAEntityManagerSPI) em).getConfiguration();
DataCacheScheduler scheduler = new DataCacheScheduler(conf);
+ // Make the scheduler run every 1 minute
scheduler.setInterval(1);
+ DummyCache cache1 = new DummyCache();
+ DummyCache cache2 = new DummyCache();
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
- int minute = (cal.get(Calendar.MINUTE) + 2) % 60;
- StringBuffer sched = new StringBuffer();
- sched.append(minute).append(' ');
- sched.append("* ");
- sched.append("* ");
- sched.append("* ");
- sched.append("* ");
- DummyCache cache = new DummyCache();
- scheduler.scheduleEviction(cache, sched.toString());
-
- Thread thread = new Thread(scheduler);
- thread.setDaemon(true);
- thread.start();
- // test that it did not run yet...
- Thread.currentThread().sleep(90 * 1000); // 90 seconds
- assertEquals(0, cache.clearCount);
- // test that it ran...
- Thread.currentThread().sleep(45 * 1000); // 45 seconds
- assertEquals(1, cache.clearCount);
- // test that it wasn't too eager
- Thread.currentThread().sleep(50 * 1000); // 90 seconds
- assertEquals(1, cache.clearCount);
- scheduler.stop();
- }*/
-
- /**
- * too slow *
- */
- /* public void XXXtestMonth()
- throws Exception {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- int month = cal.get(Calendar.MONTH);
- int month2 = month + 1;
- if (month2 > 12)
- month2 = 1;
- doTest("* * " + month + " *", "* * " + month2 + " *");
- }*/
-
- /**
- * too slow *
- */
- /* public void XXXtestDayOfMonth()
- throws Exception {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- int dom = cal.get(Calendar.DAY_OF_MONTH);
- doTest("* " + dom + " * *", "* " + (dom % 12 + 1) + " * *");
- }*/
- public void testDayOfWeek()
- throws Exception {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- int day = cal.get(Calendar.DAY_OF_WEEK);
- doTest("* * * " + day, "* * * " + (day % 7 + 1));
- }
+ int currMin = cal.get(Calendar.MINUTE);
+ int plusOne = currMin+1;
+ int plusTwo = plusOne+1;
+ if(plusOne>=60){
+ plusOne-=60;
+ }
+ if(plusTwo>=60){
+ plusTwo-=60;
+ }
+ // Schedule eviction to happen the next two minutes
+ scheduler.scheduleEviction(cache2, plusOne+","+plusTwo+" * * * *");
- public void testHour()
- throws Exception {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- int hour = cal.get(Calendar.HOUR_OF_DAY);
- doTest(hour + " * * *", ((hour + 1) % 24) + " * * *");
+ // Schedule eviction to happen every mintue on cache 1
+ scheduler.scheduleEviction(cache1, ("+1"));
+
+ Thread.currentThread().sleep(61000);
+ assertEquals(1,cache1.getClearCount());
+ assertEquals(1,cache2.getClearCount());
+
+ Thread.currentThread().sleep(60000);
+ assertEquals(2,cache1.getClearCount());
+ assertEquals(2,cache2.getClearCount());
+
+ Thread.currentThread().sleep(60000);
+ assertEquals(3,cache1.getClearCount());
+ assertEquals(2,cache2.getClearCount());
}
/**
* Pass in 4 out of 5 tokens.
*/
- private void doTest(String valid, String invalid)
- throws Exception {
-
- OpenJPAEntityManagerFactory emf =
- (OpenJPAEntityManagerFactory) getEmf();
- OpenJPAConfiguration conf =
- ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf))
- .getConfiguration();
-
- DataCacheScheduler scheduler = new DataCacheScheduler(conf);
- scheduler.setInterval(1);
-
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- String sched = ((cal.get(Calendar.MINUTE) + 1) % 60) + " ";
- DummyCache validCache = new DummyCache();
- scheduler.scheduleEviction(validCache, sched + valid);
- DummyCache invalidCache = new DummyCache();
- scheduler.scheduleEviction(invalidCache, sched + invalid);
- Thread thread = new Thread(scheduler);
- thread.setDaemon(true);
- thread.start();
- // test that it did not run yet...
- Thread.currentThread().sleep(70 * 1000); // 70 seconds
- scheduler.stop();
-// assertEquals(2, validCache.clearCount);
- assertTrue("Wrong invocation count: " + validCache.clearCount,
- validCache.clearCount == 1 || validCache.clearCount == 2);
- assertEquals(0, invalidCache.clearCount);
- }
-
+ // private void doTest(String valid, String invalid) throws Exception {
+ //
+ // OpenJPAEntityManagerFactory emf = (OpenJPAEntityManagerFactory) getEmf();
+ // OpenJPAConfiguration conf = ((OpenJPAEntityManagerFactorySPI)
+ // OpenJPAPersistence.cast(emf)).getConfiguration();
+ //
+ // DataCacheScheduler scheduler = new DataCacheScheduler(conf);
+ // scheduler.setInterval(1);
+ //
+ // Calendar cal = Calendar.getInstance();
+ // cal.setTime(new Date());
+ // String sched = ((cal.get(Calendar.MINUTE) + 1) % 60) + " ";
+ // DummyCache validCache = new DummyCache();
+ // scheduler.scheduleEviction(validCache, sched + valid);
+ // DummyCache invalidCache = new DummyCache();
+ // scheduler.scheduleEviction(invalidCache, sched + invalid);
+ // Thread thread = new Thread(scheduler);
+ // thread.setDaemon(true);
+ // thread.start();
+ // // test that it did not run yet...
+ // Thread.currentThread().sleep(70 * 1000); // 70 seconds
+ // scheduler.stop();
+ // // assertEquals(2, validCache.clearCount);
+ // assertTrue("Wrong invocation count: " + validCache.clearCount, validCache.clearCount == 1
+ // || validCache.clearCount == 2);
+ // assertEquals(0, invalidCache.clearCount);
+ // }
private class DummyCache extends ConcurrentDataCache {
int clearCount = 0;
- public void clear() {
+ public synchronized int getClearCount(){
+ return clearCount;
+ }
+ public synchronized void clear() {
clearCount++;
}
}
Modified: openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml?rev=916052&r1=916051&r2=916052&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml (original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml Thu Feb 25 00:11:33 2010
@@ -277,7 +277,7 @@
</indexterm>
A cache can specify that it should be cleared at certain times rather than using
data timeouts. The <literal>EvictionSchedule</literal> property of OpenJPA's
-cache implementation accepts a <literal>cron</literal> style eviction schedule.
+cache implementation can be input in two different formats. The first is a <literal>cron</literal> style eviction schedule.
The format of this property is a whitespace-separated list of five tokens, where
the <literal>*</literal> symbol (asterisk), indicates match all. The tokens are,
in order:
@@ -317,6 +317,20 @@
<programlisting>
true(EvictionSchedule='15,45 15 * * 1')
</programlisting>
+ <para>
+The second format for this property is an interval style eviction schedule. The
+format of this property is a <literal>+</literal> followed by the number of minutes
+between each time that the cache should be evicted.
+ </para>
+ <para>
+For example, the following openjpa.DataCache setting schedules the default cache
+to evict values from the cache every 120 minutes.
+ </para>
+ <para>
+<programlisting>
+true(EvictionSchedule='+120')
+</programlisting>
+ </para>
<section id="ref_guide_cache_distribution">
<title>Distributing instances across cache partitions</title>
<para>