geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kl...@apache.org
Subject [1/2] incubator-geode git commit: GEODE-391, GEODE-398: fix race condition in TXExpiryJUnitTest
Date Wed, 14 Oct 2015 16:55:55 GMT
Repository: incubator-geode
Updated Branches:
  refs/heads/feature/GEODE-189-new f33d5b757 -> 8efc60572


GEODE-391, GEODE-398: fix race condition in TXExpiryJUnitTest

The test now handled ExpiryTask reschedule.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/8d1ada30
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/8d1ada30
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/8d1ada30

Branch: refs/heads/feature/GEODE-189-new
Commit: 8d1ada30648acce2e09211ac20cfcb935ad77a89
Parents: 17fdf57
Author: Darrel Schneider <dschneider@pivotal.io>
Authored: Tue Oct 13 16:12:55 2015 -0700
Committer: Darrel Schneider <dschneider@pivotal.io>
Committed: Tue Oct 13 16:12:55 2015 -0700

----------------------------------------------------------------------
 .../gemfire/internal/cache/EntryExpiryTask.java |  3 ++
 .../gemfire/internal/cache/ExpiryTask.java      | 24 ++++++++-
 .../internal/cache/RegionExpiryTask.java        |  3 ++
 .../com/gemstone/gemfire/TXExpiryJUnitTest.java | 51 +++++++++++++++-----
 4 files changed, 68 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8d1ada30/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryExpiryTask.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryExpiryTask.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryExpiryTask.java
index ca9a4ef..ef47514 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryExpiryTask.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryExpiryTask.java
@@ -196,6 +196,9 @@ public class EntryExpiryTask extends ExpiryTask {
     }
     if (getExpirationTime() > 0) {
       addExpiryTask();
+      if (expiryTaskListener != null) {
+        expiryTaskListener.afterReschedule(this);
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8d1ada30/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/ExpiryTask.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/ExpiryTask.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/ExpiryTask.java
index 357c0a8..9d5795a 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/ExpiryTask.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/ExpiryTask.java
@@ -223,7 +223,11 @@ public abstract class ExpiryTask extends SystemTimer.SystemTimerTask
{
   {
     ExpirationAction action = getAction();
     if (action == null) return false;
-    return expire(action, isPending);
+    boolean result = expire(action, isPending);
+    if (result && expiryTaskListener != null) {
+      expiryTaskListener.afterExpire(this);
+    }
+    return result;
   }
   
   /** Why did this expire?
@@ -380,7 +384,7 @@ public abstract class ExpiryTask extends SystemTimer.SystemTimerTask {
        logger.fatal(LocalizedMessage.create(LocalizedStrings.ExpiryTask_EXCEPTION_IN_EXPIRATION_TASK),
ex);
     } finally {
       if (expiryTaskListener != null) {
-        expiryTaskListener.afterExpire(this);
+        expiryTaskListener.afterTaskRan(this);
       }
     }
   }
@@ -503,6 +507,22 @@ public abstract class ExpiryTask extends SystemTimer.SystemTimerTask
{
    */
   public interface ExpiryTaskListener {
     /**
+     * Called after the given expiry task has run.
+     * This means that the time it was originally
+     * scheduled to run has elapsed and the scheduler
+     * has run the task. While running the task it
+     * may decide to expire it or reschedule it.
+     */
+    public void afterTaskRan(ExpiryTask et);
+    /**
+     * Called after the given expiry task has been
+     * rescheduled. afterTaskRan can still be called
+     * on the same task.
+     * In some cases a task is rescheduled without expiring it.
+     * In others it is expired and rescheduled.
+     */
+    public void afterReschedule(ExpiryTask et);
+    /**
      * Called after the given expiry task has expired.
      */
     public void afterExpire(ExpiryTask et);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8d1ada30/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/RegionExpiryTask.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/RegionExpiryTask.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/RegionExpiryTask.java
index 68c4e3e..e17ad58 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/RegionExpiryTask.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/RegionExpiryTask.java
@@ -120,6 +120,9 @@ abstract class RegionExpiryTask extends ExpiryTask
     }
 
     addExpiryTask();
+    if (expiryTaskListener != null) {
+      expiryTaskListener.afterReschedule(this);
+    }
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8d1ada30/gemfire-core/src/test/java/com/gemstone/gemfire/TXExpiryJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/TXExpiryJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/TXExpiryJUnitTest.java
index 867ebb2..ae94002 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/TXExpiryJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/TXExpiryJUnitTest.java
@@ -231,21 +231,27 @@ public class TXExpiryJUnitTest {
   }
   
   private void waitForEntryExpiration(LocalRegion lr, String key) {
-    ExpirationDetector detector = new ExpirationDetector(lr.getEntryExpiryTask(key));
-    ExpiryTask.expiryTaskListener = detector;
     try {
-      ExpiryTask.permitExpiration();
-      DistributedTestCase.waitForCriterion(detector, 3000, 2, true);
+      ExpirationDetector detector;
+      do {
+        detector = new ExpirationDetector(lr.getEntryExpiryTask(key));
+        ExpiryTask.expiryTaskListener = detector;
+        ExpiryTask.permitExpiration();
+        DistributedTestCase.waitForCriterion(detector, 3000, 2, true);
+      } while (!detector.hasExpired() && detector.wasRescheduled());
     } finally {
       ExpiryTask.expiryTaskListener = null;
     }
   }
   private void waitForRegionExpiration(LocalRegion lr, boolean ttl) {
-    ExpirationDetector detector = new ExpirationDetector(ttl ? lr.getRegionTTLExpiryTask()
: lr.getRegionIdleExpiryTask());
-    ExpiryTask.expiryTaskListener = detector;
     try {
-      ExpiryTask.permitExpiration();
-      DistributedTestCase.waitForCriterion(detector, 3000, 2, true);
+      ExpirationDetector detector;
+      do {
+        detector = new ExpirationDetector(ttl ? lr.getRegionTTLExpiryTask() : lr.getRegionIdleExpiryTask());
+        ExpiryTask.expiryTaskListener = detector;
+        ExpiryTask.permitExpiration();
+        DistributedTestCase.waitForCriterion(detector, 3000, 2, true);
+      } while (!detector.hasExpired() && detector.wasRescheduled());
     } finally {
       ExpiryTask.expiryTaskListener = null;
     }
@@ -256,25 +262,48 @@ public class TXExpiryJUnitTest {
    * Used to detect that a particular ExpiryTask has expired.
    */
   public static class ExpirationDetector implements ExpiryTaskListener, WaitCriterion {
+    private volatile boolean ran = false;
     private volatile boolean expired = false;
-    private final ExpiryTask et;
+    private volatile boolean rescheduled = false;
+    public final ExpiryTask et;
     public ExpirationDetector(ExpiryTask et) {
       assertNotNull(et);
       this.et = et;
     }
     @Override
+    public void afterReschedule(ExpiryTask et) {
+      if (et == this.et) {
+        if (!hasExpired()) {
+          ExpiryTask.suspendExpiration();
+        }
+        this.rescheduled = true;
+      }
+    }
+    @Override
     public void afterExpire(ExpiryTask et) {
       if (et == this.et) {
         this.expired = true;
       }
     }
     @Override
+    public void afterTaskRan(ExpiryTask et) {
+      if (et == this.et) {
+        this.ran = true;
+      }
+    }
+    @Override
     public boolean done() {
-      return this.expired;
+      return this.ran;
     }
     @Override
     public String description() {
-      return "the expiry task " + this.et + " did not expire";
+      return "the expiry task " + this.et + " never ran";
+    }
+    public boolean wasRescheduled() {
+      return this.rescheduled;
+    }
+    public boolean hasExpired() {
+      return this.expired;
     }
   }
 


Mime
View raw message