You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ds...@apache.org on 2015/10/14 01:24:06 UTC
incubator-geode git commit: GEODE-391,
GEODE-398: fix race condition in TXExpiryJUnitTest
Repository: incubator-geode
Updated Branches:
refs/heads/develop 17fdf57fd -> 8d1ada306
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/develop
Commit: 8d1ada30648acce2e09211ac20cfcb935ad77a89
Parents: 17fdf57
Author: Darrel Schneider <ds...@pivotal.io>
Authored: Tue Oct 13 16:12:55 2015 -0700
Committer: Darrel Schneider <ds...@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;
}
}