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>