[jbpm-commits] JBoss JBPM SVN: r1947 - in jbpm3/trunk/modules/jpdl/core: src/main/java/org/jbpm/db and 3 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Aug 21 01:15:18 EDT 2008


Author: alex.guizar at jboss.com
Date: 2008-08-21 01:15:18 -0400 (Thu, 21 Aug 2008)
New Revision: 1947

Modified:
   jbpm3/trunk/modules/jpdl/core/pom.xml
   jbpm3/trunk/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java
   jbpm3/trunk/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java
   jbpm3/trunk/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
   jbpm3/trunk/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java
Log:
fixed process end race condition in TimerOnTimerDbTest; removed that test from the test suite exclusions: JBPM-1135
replaced individual timer elimination in JobSession.cancelTimersByName with bulk delete
enabled timer bulk deletes to remove repeating timers immediately instead of having the timer delete itself on the next repetition

Modified: jbpm3/trunk/modules/jpdl/core/pom.xml
===================================================================
--- jbpm3/trunk/modules/jpdl/core/pom.xml	2008-08-20 22:09:12 UTC (rev 1946)
+++ jbpm3/trunk/modules/jpdl/core/pom.xml	2008-08-21 05:15:18 UTC (rev 1947)
@@ -195,7 +195,6 @@
                   <exclude>org/jbpm/persistence/db/PersistenceConfigurationTest.java</exclude>
                   <exclude>org/jbpm/scheduler/exe/UnsafeSessionUsageTest.java</exclude>
                   <exclude>org/jbpm/seam/SeamPageFlowTest.java</exclude>
-                  <exclude>org/jbpm/job/executor/TimerOnTimerDbTest.java</exclude>
                </excludes>
             </configuration>
          </plugin>

Modified: jbpm3/trunk/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java
===================================================================
--- jbpm3/trunk/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java	2008-08-20 22:09:12 UTC (rev 1946)
+++ jbpm3/trunk/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java	2008-08-21 05:15:18 UTC (rev 1947)
@@ -153,23 +153,12 @@
 
   public void cancelTimersByName(String name, Token token) {
     try {
-      // the bulk delete was replaced with a query and session.deletes on 
-      // the retrieved elements to prevent stale object exceptions.  
-      // With a bulk delete, the hibernate session is not aware and gives a problem 
-      // if a later session.delete doesn't return 1.
-      Query query = session.getNamedQuery("JobSession.getTimersByName");
+      log.debug("canceling timers by name " + name + " for " + token);
+      Query query = session.getNamedQuery("JobSession.deleteTimersByName");
       query.setString("name", name);
       query.setParameter("token", token);
-      List results = query.list();
-      if (results!=null) {
-        Iterator iter = results.iterator();
-        while (iter.hasNext()) {
-          Timer timer = (Timer) iter.next();
-          log.debug("deleting "+timer+" for '"+token+"'");
-          session.delete(timer);
-        }
-      }
-
+      int entityCount = query.executeUpdate();
+      log.debug(entityCount+" timers by name " + name + " for " + token + " were deleted");
     } catch (Exception e) {
       log.error(e);
       throw new JbpmException("couldn't cancel timers by name '"+name+"' for '"+token+"'", e);

Modified: jbpm3/trunk/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java
===================================================================
--- jbpm3/trunk/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java	2008-08-20 22:09:12 UTC (rev 1946)
+++ jbpm3/trunk/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java	2008-08-21 05:15:18 UTC (rev 1947)
@@ -35,11 +35,6 @@
   }
 
   public boolean execute(JbpmContext jbpmContext) throws Exception {
-    if (processInstance.hasEnded()) {
-      // happens when a repeating timer is blocked at the time the process instance ends
-      return true;
-    }
-
     ExecutionContext executionContext = new ExecutionContext(token);
     executionContext.setTimer(this);
 

Modified: jbpm3/trunk/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
===================================================================
--- jbpm3/trunk/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml	2008-08-20 22:09:12 UTC (rev 1946)
+++ jbpm3/trunk/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml	2008-08-21 05:15:18 UTC (rev 1947)
@@ -304,14 +304,14 @@
       where job.token = :token
     ]]>
   </query>
-  
-  <query name="JobSession.getTimersByName">
+
+  <query name="JobSession.deleteTimersByName">
     <![CDATA[
-      select timer
-      from org.jbpm.job.Timer timer
+      delete from org.jbpm.job.Timer timer
       where timer.token = :token
         and timer.name = :name
-        and timer.lockOwner is null
+        and (timer.lockOwner is null
+         or timer.repeat is not null)
     ]]>
   </query>
 
@@ -319,7 +319,8 @@
     <![CDATA[
       delete from org.jbpm.job.Timer timer
       where timer.processInstance = :processInstance
-        and timer.lockOwner is null
+        and (timer.lockOwner is null
+         or timer.repeat is not null)
     ]]>
   </query>
 

Modified: jbpm3/trunk/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java
===================================================================
--- jbpm3/trunk/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java	2008-08-20 22:09:12 UTC (rev 1946)
+++ jbpm3/trunk/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java	2008-08-21 05:15:18 UTC (rev 1947)
@@ -23,6 +23,11 @@
 
 import java.io.Serializable;
 
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.jbpm.db.AbstractDbTestCase;
 import org.jbpm.graph.def.Event;
 import org.jbpm.graph.def.ProcessDefinition;
@@ -41,24 +46,23 @@
     ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("timerTest");
     processInstance.getContextInstance().setVariable("testCallback", new TestCallback());
     processInstance.signal();
-    long tokenId = processInstance.getRootToken().getId();
+    assertEquals("firstNode", processInstance.getRootToken().getNode().getName());
     commitAndCloseSession();
 
     startJobExecutor();
     try {
       TestCallback.waitForEvent(Event.EVENTTYPE_NODE_ENTER);
       beginSessionTransaction();
-      assertEquals("firstNode", jbpmContext.loadToken(tokenId).getNode().getName());
+      long processInstanceId = processInstance.getId();
+      assertEquals("secondNode", jbpmContext.loadProcessInstance(processInstanceId)
+          .getRootToken()
+          .getNode()
+          .getName());
       commitAndCloseSession();
 
-      TestCallback.waitForEvent(Event.EVENTTYPE_NODE_ENTER);
-      beginSessionTransaction();
-      assertEquals("secondNode", jbpmContext.loadToken(tokenId).getNode().getName());
-      commitAndCloseSession();
-
       TestCallback.waitForEvent(Event.EVENTTYPE_PROCESS_END);
       beginSessionTransaction();
-      assertTrue(jbpmContext.loadToken(tokenId).hasEnded());
+      assertTrue(jbpmContext.loadProcessInstance(processInstanceId).hasEnded());
     }
     finally {
       stopJobExecutor();
@@ -68,55 +72,63 @@
   public static class TestCallback implements Serializable {
 
     private static final long serialVersionUID = 1L;
+    private static final Log log = LogFactory.getLog(TestCallback.class);
 
     public void processStart() {
-      synchronized (Event.EVENTTYPE_PROCESS_START) {
-        Event.EVENTTYPE_PROCESS_START.notify();
-      }
+      registerNotification(Event.EVENTTYPE_PROCESS_START);
     }
 
     public void processEnd() {
-      synchronized (Event.EVENTTYPE_PROCESS_END) {
-        Event.EVENTTYPE_PROCESS_END.notify();
-      }
+      registerNotification(Event.EVENTTYPE_PROCESS_END);
     }
 
     public void nodeEnter() {
-      synchronized (Event.EVENTTYPE_NODE_ENTER) {
-        Event.EVENTTYPE_NODE_ENTER.notify();
-      }
+      registerNotification(Event.EVENTTYPE_NODE_ENTER);
     }
 
     public void nodeLeave() {
-      synchronized (Event.EVENTTYPE_NODE_LEAVE) {
-        Event.EVENTTYPE_NODE_LEAVE.notify();
-      }
+      registerNotification(Event.EVENTTYPE_NODE_LEAVE);
     }
 
     public void taskCreate() {
-      synchronized (Event.EVENTTYPE_TASK_CREATE) {
-        Event.EVENTTYPE_TASK_CREATE.notify();
-      }
+      registerNotification(Event.EVENTTYPE_TASK_CREATE);
     }
 
     public void taskEnd() {
-      synchronized (Event.EVENTTYPE_TASK_END) {
-        Event.EVENTTYPE_TASK_END.notify();
-      }
+      registerNotification(Event.EVENTTYPE_TASK_END);
     }
 
     public void timerCreate() {
-      synchronized (Event.EVENTTYPE_TIMER_CREATE) {
-        Event.EVENTTYPE_TIMER_CREATE.notify();
-      }
+      registerNotification(Event.EVENTTYPE_TIMER_CREATE);
     }
 
     public void timer() {
-      synchronized (Event.EVENTTYPE_TIMER) {
-        Event.EVENTTYPE_TIMER.notify();
-      }
+      registerNotification(Event.EVENTTYPE_TIMER);
     }
 
+    private static void registerNotification(final String event) {
+      Synchronization notification = new Synchronization() {
+
+        public void beforeCompletion() {
+          // nothing to do here
+        }
+
+        public void afterCompletion(int status) {
+          if (status == Status.STATUS_COMMITTED) {
+            log.info("delivering " + event + " notification");
+            synchronized (event) {
+              event.notify();
+            }
+          }
+        }
+
+      };
+      jbpmConfiguration.getCurrentJbpmContext()
+          .getSession()
+          .getTransaction()
+          .registerSynchronization(notification);
+    }
+
     public static void waitForEvent(String event) {
       synchronized (event) {
         try {




More information about the jbpm-commits mailing list