Bug 975092

Summary: Fork/Join with async nodes and variable updates fails
Product: [JBoss] JBoss Enterprise SOA Platform 5 Reporter: Martin Weiler <mweiler>
Component: JBPM - standalone, JBPM - within SOAAssignee: Nobody <nobody>
Status: CLOSED UPSTREAM QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: 5.3.1CC: nwallace, soa-p-jira
Target Milestone: GA   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2025-02-10 03:27:57 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 986007    
Attachments:
Description Flags
Added stack trace (from support case). none

Description Martin Weiler 2013-06-17 15:47:59 UTC
Description of problem:
Platform issue for JBPM-4031

Comment 1 JBoss JIRA Server 2013-06-18 14:28:39 UTC
Martin Weiler <mweiler> made a comment on jira JBPM-4031

Proposal to fix this issue:

{code}
diff --git a/core/src/main/resources/org/jbpm/context/exe/ContextInstance.hbm.xml b/core/src/main/resources/org/jbpm/context/exe/ContextInstance.hbm.xml
index 300a612..d0fd5ab 100644
--- a/core/src/main/resources/org/jbpm/context/exe/ContextInstance.hbm.xml
+++ b/core/src/main/resources/org/jbpm/context/exe/ContextInstance.hbm.xml
@@ -10,7 +10,7 @@
             extends="org.jbpm.module.exe.ModuleInstance" 
             discriminator-value="C">
   
-    <map name="tokenVariableMaps" cascade="all" inverse="true">
+    <map name="tokenVariableMaps" cascade="all" inverse="true" optimistic-lock="false">
       <!-- add on-delete for optimized deletion 
       <key column="CONTEXTINSTANCE_" on-delete="cascade" />
       -->
{code}

This fix prevents the ContextInstance version to be incremented during the update of the TokenVariableMap. As a result, the process execution is no longer failing with a race condition.

But there is a caveat: if all nodes inside the fork/join are async with no wait states, the parent node will not be signaled automatically out of the join when all child tokens arrive.

Comment 2 Marco Rietveld 2013-06-25 17:31:47 UTC
Created attachment 765213 [details]
Added stack trace (from support case).

Comment 5 JBoss JIRA Server 2013-06-26 15:00:17 UTC
Marco Rietveld <marco.rietveld> made a comment on jira JBPM-4031

I've looked at a bunch of different hibernate 3 mapping options, and started to look at possible hibernate session tricks (tx synchs? session.refresh()?), but luckily, I ran into JBPM-2948, which Brad Davis implemented. 

One possible solution for this user would be to implement his process using the functionality described there, which basically means using async subprocesses instead of async nodes. I'll let you know when I have a working test for this.

Comment 6 JBoss JIRA Server 2013-07-10 07:02:09 UTC
Toshiya Kobayashi <tkobayas> made a comment on jira JBPM-4031

Hi Marco,

How about this fix? (attached as JBPM-4031.patch)

{code:java}
diff --git a/core/src/main/java/org/jbpm/context/exe/ContextInstance.java b/core/src/main/java/org/jbpm/context/exe/ContextInstance.java
index 322ae11..c15b4a6 100644
--- a/core/src/main/java/org/jbpm/context/exe/ContextInstance.java
+++ b/core/src/main/java/org/jbpm/context/exe/ContextInstance.java
@@ -330,7 +330,7 @@ public class ContextInstance extends ModuleInstance {
     return tokenVariableMap;
   }
 
-  private TokenVariableMap createTokenVariableMap(Token token) {
+  public TokenVariableMap createTokenVariableMap(Token token) {
     if (tokenVariableMaps == null) {
       tokenVariableMaps = new HashMap();
     }
diff --git a/core/src/main/java/org/jbpm/graph/node/Fork.java b/core/src/main/java/org/jbpm/graph/node/Fork.java
index 026443c..7229be4 100644
--- a/core/src/main/java/org/jbpm/graph/node/Fork.java
+++ b/core/src/main/java/org/jbpm/graph/node/Fork.java
@@ -115,6 +115,8 @@ public class Fork extends Node {
       if( ! parentChildTokens.containsKey(transitionName)) { 
         parentChildTokens.put(transitionName, childToken);
       }
+      // JBPM-4031 : Create TokenVariableMap for each child token beforehand
+      executionContext.getContextInstance().createTokenVariableMap(childToken);
     }
 
     // phase three: branch child tokens from the fork into the transitions
{code}

I have verified it with JBPM4031Test.testVariablesAfterFork() and manual test in SOA-P 5.3.1.

Comment 7 JBoss JIRA Server 2013-07-10 07:04:18 UTC
Toshiya Kobayashi <tkobayas> made a comment on jira JBPM-4031

ContextInstance.getOrCreateTokenVariableMap() is not useful in this case because it returns TokenVariableMap of its parent token. So I use createTokenVariableMap() instead.

Comment 8 JBoss JIRA Server 2013-07-18 20:58:36 UTC
Marco Rietveld <marco.rietveld> made a comment on jira JBPM-4031

I've applied to the patch to the code and tested it. It's good!

Comment 10 JBoss JIRA Server 2013-07-18 20:59:57 UTC
Marco Rietveld <marco.rietveld> updated the status of jira JBPM-4031 to Resolved

Comment 14 Red Hat Bugzilla 2025-02-10 03:27:57 UTC
This product has been discontinued or is no longer tracked in Red Hat Bugzilla.