You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by gd...@apache.org on 2004/07/21 05:53:44 UTC
cvs commit: incubator-geronimo/modules/timer/src/java/org/apache/geronimo/timer ThreadPooledTimer.java ExecutorFeedingTimerTask.java
gdamour 2004/07/20 20:53:44
Modified: modules/timer/src/test/org/apache/geronimo/timer
AbstractThreadPooledTimerTest.java
modules/timer/src/java/org/apache/geronimo/timer
ThreadPooledTimer.java
ExecutorFeedingTimerTask.java
Log:
If a timer is cancelled in the scope of a transaction, then it must not be executed even if the transaction has
not yet been committed.
If a timer is cancelled in the scope of a rolled back transaction, then it must be restored as if its cancel method
had not been called.
Revision Changes Path
1.3 +24 -4 incubator-geronimo/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java
Index: AbstractThreadPooledTimerTest.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AbstractThreadPooledTimerTest.java 20 Jul 2004 23:36:53 -0000 1.2
+++ AbstractThreadPooledTimerTest.java 21 Jul 2004 03:53:43 -0000 1.3
@@ -145,7 +145,7 @@
assertEquals(COUNT, counter.get());
}
- public void testCancelInTransaction() throws Exception {
+ public void testCancelInCommittedTransaction() throws Exception {
Thread.currentThread().sleep(SLOP + DELAY);
WorkInfo[] workInfos = new WorkInfo[COUNT];
for (long i = 0; i < COUNT; i++) {
@@ -158,10 +158,30 @@
workInfos[i].getExecutorFeedingTimerTask().cancel();
}
Thread.currentThread().sleep(SLOP + DELAY);
- assertEquals(2 * COUNT, counter.get());
+ assertEquals(COUNT, counter.get());
transactionContext.commit();
Thread.currentThread().sleep(SLOP + DELAY);
- assertEquals(2 * COUNT, counter.get());
+ assertEquals(COUNT, counter.get());
+ }
+
+ public void testCancelInRolledBackTransaction() throws Exception {
+ Thread.currentThread().sleep(SLOP + DELAY);
+ WorkInfo[] workInfos = new WorkInfo[COUNT];
+ for (long i = 0; i < COUNT; i++) {
+ workInfos[(int) i] = timer.scheduleAtFixedRate(key, userTaskFactory, userId, userKey, DELAY, DELAY);
+ }
+ Thread.currentThread().sleep(SLOP + DELAY);
+ assertEquals(COUNT, counter.get());
+ TransactionContext transactionContext = transactionContextManager.newContainerTransactionContext();
+ for (int i = 0; i < workInfos.length; i++) {
+ workInfos[i].getExecutorFeedingTimerTask().cancel();
+ }
+ Thread.currentThread().sleep(SLOP + DELAY);
+ assertEquals(COUNT, counter.get());
+ transactionContext.rollback();
+ Thread.currentThread().sleep(SLOP + DELAY);
+ // Catches up with two periods.
+ assertEquals(3 * COUNT, counter.get());
}
public void testRepeatCountFromPersisted() throws Exception {
1.3 +3 -3 incubator-geronimo/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java
Index: ThreadPooledTimer.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ThreadPooledTimer.java 20 Jul 2004 23:36:53 -0000 1.2
+++ ThreadPooledTimer.java 21 Jul 2004 03:53:43 -0000 1.3
@@ -146,7 +146,7 @@
}
}
- private void addWorkInfo(WorkInfo worker) {
+ void addWorkInfo(WorkInfo worker) {
idToWorkInfoMap.put(new Long(worker.getId()), worker);
}
@@ -166,7 +166,7 @@
}
}
- private Timer getTimer() {
+ Timer getTimer() {
if (delegate == null) {
throw new IllegalStateException("Timer is stopped");
}
1.2 +37 -9 incubator-geronimo/modules/timer/src/java/org/apache/geronimo/timer/ExecutorFeedingTimerTask.java
Index: ExecutorFeedingTimerTask.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/timer/src/java/org/apache/geronimo/timer/ExecutorFeedingTimerTask.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ExecutorFeedingTimerTask.java 18 Jul 2004 22:10:56 -0000 1.1
+++ ExecutorFeedingTimerTask.java 21 Jul 2004 03:53:44 -0000 1.2
@@ -17,6 +17,7 @@
package org.apache.geronimo.timer;
+import java.util.Date;
import java.util.TimerTask;
import javax.transaction.RollbackException;
@@ -54,11 +55,9 @@
}
public boolean cancel() {
- try {
- threadPooledTimer.getWorkerPersistence().cancel(workInfo.getId());
- } catch (PersistenceException e) {
- log.warn(e);
- }
+ // TODO double-check if this is indeed the mechanism use to raise
+ // a NoSuchObjectLocalException exception.
+ threadPooledTimer.removeWorkInfo(workInfo);
try {
threadPooledTimer.registerSynchronization(new CancelSynchronization(this));
} catch (RollbackException e) {
@@ -68,14 +67,41 @@
log.info(e);
throw (IllegalStateException) new IllegalStateException("SystemException when trying to register cacel synchronization").initCause(e);
}
- //return value is meaningless.
- return true;
+ // One cancels the task at this specific time. If the transaction is
+ // rolled-back, one will recreate it.
+ return super.cancel();
}
private void doCancel() {
- super.cancel();
+ try {
+ // Impacts the timer storage only if the timer is cancelled
+ // in the scope of a committed transactions.
+ threadPooledTimer.getWorkerPersistence().cancel(workInfo.getId());
+ } catch (PersistenceException e) {
+ log.warn(e);
+ }
}
+ private void rollbackCancel() {
+ threadPooledTimer.addWorkInfo(workInfo);
+
+ // The transaction has been rolled-back, we need to restore the
+ // task as if cancel has been called.
+ if ( workInfo.isOneTime() ) {
+ threadPooledTimer.getTimer().schedule(
+ new ExecutorFeedingTimerTask(workInfo, threadPooledTimer),
+ workInfo.getTime());
+ } else if ( workInfo.getAtFixedRate() ) {
+ threadPooledTimer.getTimer().scheduleAtFixedRate(
+ new ExecutorFeedingTimerTask(workInfo, threadPooledTimer),
+ workInfo.getTime(), workInfo.getPeriod().longValue());
+ } else {
+ threadPooledTimer.getTimer().schedule(
+ new ExecutorFeedingTimerTask(workInfo, threadPooledTimer),
+ workInfo.getTime(), workInfo.getPeriod().longValue());
+ }
+ }
+
private static class CancelSynchronization implements Synchronization {
private final ExecutorFeedingTimerTask worker;
@@ -90,6 +116,8 @@
public void afterCompletion(int status) {
if (status == Status.STATUS_COMMITTED) {
worker.doCancel();
+ } else if (status == Status.STATUS_ROLLEDBACK) {
+ worker.rollbackCancel();
}
}