[jbpm-commits] JBoss JBPM SVN: r5137 - in jbpm3/branches/jbpm-3.2-soa/modules/core/src: main/java/org/jbpm/graph/node and 5 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Sat Jun 27 08:56:00 EDT 2009
Author: alex.guizar at jboss.com
Date: 2009-06-27 08:56:00 -0400 (Sat, 27 Jun 2009)
New Revision: 5137
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/ContextInstance.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/Join.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/jta/JtaDbPersistenceService.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/perf/SimplePerformanceTest.java
Log:
JBPM-2115: jBPM testsuite hangs when executed with DB2 (CODING IN PROGRESS)
Prevent JobExecutorThread from waiting 5 sec after LockAcquisitionException
Start job executor after starting processes in SimplePerformanceTest to avoid concurrency and allow measurements with HSQL
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/ContextInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/ContextInstance.java 2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/ContextInstance.java 2009-06-27 12:56:00 UTC (rev 5137)
@@ -31,391 +31,341 @@
import org.jbpm.module.exe.ModuleInstance;
/**
- * maintains all the key-variable pairs for a process instance. You can obtain a
- * ContextInstance from a processInstance from a process instance like this :
+ * maintains all the key-variable pairs for a process instance. You can obtain a ContextInstance
+ * from a processInstance from a process instance like this :
+ *
* <pre>
* ProcessInstance processInstance = ...;
* ContextInstance contextInstance = processInstance.getContextInstance();
* </pre>
- * More information on context and process variableInstances can be found in
- * <a href="../../../../../userguide/en/html/reference.html#context">the userguide, section context</a>
+ *
+ * More information on context and process variableInstances can be found in <a
+ * href="../../../../../userguide/en/html/reference.html#context">the userguide, section context</a>
*/
-public class ContextInstance extends ModuleInstance
-{
+public class ContextInstance extends ModuleInstance {
private static final long serialVersionUID = 1L;
- // maps Token's to TokenVariableMap's
+ // maps Tokens to TokenVariableMaps
protected Map tokenVariableMaps = null;
- // maps variablenames (String) to values (Object)
+ // maps variable names (String) to values (Object)
protected transient Map transientVariables = null;
protected transient List updatedVariableContainers = null;
- public ContextInstance()
- {
+ public ContextInstance() {
}
// normal variableInstances (persistent) ////////////////////////////////////
- /*
- * creates a variable on the root-token (= process-instance scope) and calculates the actual VariableInstance-type from the value.
+ /**
+ * creates a variable on the root-token (= process-instance scope) and calculates the actual
+ * VariableInstance-type from the value.
*/
- public void createVariable(String name, Object value)
- {
+ public void createVariable(String name, Object value) {
setVariableLocally(name, value, getRootToken());
}
- /*
- * sets the variable on the root token, creates the variable if necessary and calculates the actual VariableInstance-type from the value.
+ /**
+ * sets the variable on the root token, creates the variable if necessary and calculates the
+ * actual VariableInstance-type from the value.
*/
- public void setVariableLocally(String name, Object value)
- {
+ public void setVariableLocally(String name, Object value) {
setVariableLocally(name, value, getRootToken());
}
- /*
- * creates a variable in the scope of the given token and calculates the actual VariableInstance-type from the value.
+ /**
+ * creates a variable in the scope of the given token and calculates the actual
+ * VariableInstance-type from the value.
*/
- public void createVariable(String name, Object value, Token token)
- {
+ public void createVariable(String name, Object value, Token token) {
setVariableLocally(name, value, token);
}
- /*
- * creates a variable in the scope of the given token and calculates the actual VariableInstance-type from the value.
+ /**
+ * creates a variable in the scope of the given token and calculates the actual
+ * VariableInstance-type from the value.
*/
- public void setVariableLocally(String name, Object value, Token token)
- {
+ public void setVariableLocally(String name, Object value, Token token) {
TokenVariableMap tokenVariableMap = createTokenVariableMap(token);
tokenVariableMap.setVariableLocally(name, value);
}
- /*
+ /**
* gets all the variableInstances on the root-token (= process-instance scope).
*/
- public Map getVariables()
- {
+ public Map getVariables() {
return getVariables(getRootToken());
}
- /*
+ /**
* retrieves all the variableInstances in scope of the given token.
*/
- public Map getVariables(Token token)
- {
- Map variables = null;
-
+ public Map getVariables(Token token) {
TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
- if (tokenVariableMap != null)
- {
- variables = tokenVariableMap.getVariables();
- }
-
- return variables;
+ return tokenVariableMap != null ? tokenVariableMap.getVariables() : null;
}
- /*
+ /**
* adds all the variableInstances on the root-token (= process-instance scope).
*/
- public void addVariables(Map variables)
- {
+ public void addVariables(Map variables) {
setVariables(variables, getRootToken());
}
- /*
- * The method setVariables is the same as the {@link #addVariables(Map, Token)}, but it was added for more consistency.
+ /**
+ * The method setVariables is the same as the {@link #addVariables(Map, Token)}, but it was added
+ * for more consistency.
*/
- public void setVariables(Map variables)
- {
+ public void setVariables(Map variables) {
setVariables(variables, getRootToken());
}
- /*
- * adds all the variableInstances to the scope of the given token. This method delegates to {@link #setVariables(Map, Token)}. The method setVariables was added for
- * more consistency.
+ /**
+ * adds all the variableInstances to the scope of the given token. This method delegates to
+ * {@link #setVariables(Map, Token)}. The method setVariables was added for more consistency.
*/
- public void addVariables(Map variables, Token token)
- {
+ public void addVariables(Map variables, Token token) {
setVariables(variables, token);
}
- /*
- * adds all the variableInstances to the scope of the given token. The method setVariables is the same as the {@link #addVariables(Map, Token)}, but it was added for
- * more consistency.
+ /**
+ * adds all the variableInstances to the scope of the given token. The method setVariables is the
+ * same as the {@link #addVariables(Map, Token)}, but it was added for more consistency.
*/
- public void setVariables(Map variables, Token token)
- {
+ public void setVariables(Map variables, Token token) {
// [JBPM-1778] Empty map variables on process creation is set as null
TokenVariableMap tokenVariableMap = getOrCreateTokenVariableMap(token);
Iterator iter = variables.entrySet().iterator();
- while (iter.hasNext())
- {
- Map.Entry entry = (Map.Entry)iter.next();
- String name = (String)entry.getKey();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String name = (String) entry.getKey();
Object value = entry.getValue();
tokenVariableMap.setVariable(name, value);
}
}
- /*
+ /**
* gets the variable with the given name on the root-token (= process-instance scope).
*/
- public Object getVariable(String name)
- {
+ public Object getVariable(String name) {
return getVariable(name, getRootToken());
}
- /*
- * retrieves a variable in the scope of the token. If the given token does not have a variable for the given name, the variable is searched for up the token
- * hierarchy.
+ /**
+ * retrieves a variable in the scope of the token. If the given token does not have a variable for
+ * the given name, the variable is searched for up the token hierarchy.
*/
- public Object getVariable(String name, Token token)
- {
+ public Object getVariable(String name, Token token) {
Object variable = null;
TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
- if (tokenVariableMap != null)
- {
+ if (tokenVariableMap != null) {
variable = tokenVariableMap.getVariable(name);
}
return variable;
}
- /*
- * retrieves a variable which is local to the token. Method {@link #getVariableLocally(String, Token)} is the same as this method and it was added for naming
- * consistency.
+ /**
+ * retrieves a variable which is local to the token. Method
+ * {@link #getVariableLocally(String, Token)} is the same as this method and it was added for
+ * naming consistency.
*/
- public Object getLocalVariable(String name, Token token)
- {
+ public Object getLocalVariable(String name, Token token) {
return getVariableLocally(name, token);
}
- /*
- * retrieves a variable which is local to the token. this method was added for naming consistency. it is the same as {@link #getLocalVariable(String, Token)}.
+ /**
+ * retrieves a variable which is local to the token. this method was added for naming consistency.
+ * it is the same as {@link #getLocalVariable(String, Token)}.
*/
- public Object getVariableLocally(String name, Token token)
- {
+ public Object getVariableLocally(String name, Token token) {
Object variable = null;
- if (tokenVariableMaps != null && tokenVariableMaps.containsKey(token))
- {
- TokenVariableMap tokenVariableMap = (TokenVariableMap)tokenVariableMaps.get(token);
- if (tokenVariableMap != null)
- {
+ if (tokenVariableMaps != null && tokenVariableMaps.containsKey(token)) {
+ TokenVariableMap tokenVariableMap = (TokenVariableMap) tokenVariableMaps.get(token);
+ if (tokenVariableMap != null) {
variable = tokenVariableMap.getVariableLocally(name);
}
}
return variable;
}
- /*
+ /**
* sets a variable on the process instance scope.
*/
- public void setVariable(String name, Object value)
- {
+ public void setVariable(String name, Object value) {
setVariable(name, value, getRootToken());
}
- /*
- * sets a variable. If a variable exists in the scope given by the token, that variable is updated. Otherwise, the variable is created on the root token (=process
- * instance scope).
+ /**
+ * sets a variable. If a variable exists in the scope given by the token, that variable is
+ * updated. Otherwise, the variable is created on the root token (=process instance scope).
*/
- public void setVariable(String name, Object value, Token token)
- {
+ public void setVariable(String name, Object value, Token token) {
TokenVariableMap tokenVariableMap = getOrCreateTokenVariableMap(token);
tokenVariableMap.setVariable(name, value);
}
- /*
- * checks if a variable is present with the given name on the root-token (= process-instance scope).
+ /**
+ * checks if a variable is present with the given name on the root-token (= process-instance
+ * scope).
*/
- public boolean hasVariable(String name)
- {
+ public boolean hasVariable(String name) {
return hasVariable(name, getRootToken());
}
- /*
+ /**
* checks if a variable is present with the given name in the scope of the token.
*/
- public boolean hasVariable(String name, Token token)
- {
+ public boolean hasVariable(String name, Token token) {
boolean hasVariable = false;
TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
- if (tokenVariableMap != null)
- {
+ if (tokenVariableMap != null) {
hasVariable = tokenVariableMap.hasVariable(name);
}
return hasVariable;
}
- /*
+ /**
* deletes the given variable on the root-token (=process-instance scope).
*/
- public void deleteVariable(String name)
- {
+ public void deleteVariable(String name) {
deleteVariable(name, getRootToken());
}
- /*
- * deletes a variable from the given token. For safety reasons, this method does not propagate the deletion to parent tokens in case the given token does not contain
- * the variable.
+ /**
+ * deletes a variable from the given token. For safety reasons, this method does not propagate the
+ * deletion to parent tokens in case the given token does not contain the variable.
*/
- public void deleteVariable(String name, Token token)
- {
+ public void deleteVariable(String name, Token token) {
TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
- if (tokenVariableMap != null)
- {
+ if (tokenVariableMap != null) {
tokenVariableMap.deleteVariable(name);
}
}
// transient variableInstances //////////////////////////////////////////////
- /*
+ /**
* retrieves the transient variable for the given name.
*/
- public Object getTransientVariable(String name)
- {
+ public Object getTransientVariable(String name) {
Object transientVariable = null;
- if (transientVariables != null)
- {
+ if (transientVariables != null) {
transientVariable = transientVariables.get(name);
}
return transientVariable;
}
- /*
+ /**
* sets the transient variable for the given name to the given value.
*/
- public void setTransientVariable(String name, Object value)
- {
- if (transientVariables == null)
- {
+ public void setTransientVariable(String name, Object value) {
+ if (transientVariables == null) {
transientVariables = new HashMap();
}
transientVariables.put(name, value);
}
- /*
+ /**
* tells if a transient variable with the given name is present.
*/
- public boolean hasTransientVariable(String name)
- {
- if (transientVariables == null)
- {
+ public boolean hasTransientVariable(String name) {
+ if (transientVariables == null) {
return false;
}
return transientVariables.containsKey(name);
}
- /*
- * retrieves all the transient variableInstances map. note that no deep copy is performed, changing the map leads to changes in the transient variableInstances of
- * this context instance.
+ /**
+ * retrieves all the transient variableInstances map. note that no deep copy is performed,
+ * changing the map leads to changes in the transient variableInstances of this context instance.
*/
- public Map getTransientVariables()
- {
+ public Map getTransientVariables() {
return transientVariables;
}
- /*
+ /**
* replaces the transient variableInstances with the given map.
*/
- public void setTransientVariables(Map transientVariables)
- {
+ public void setTransientVariables(Map transientVariables) {
this.transientVariables = transientVariables;
}
- /*
+ /**
* removes the transient variable.
*/
- public void deleteTransientVariable(String name)
- {
- if (transientVariables == null)
- return;
+ public void deleteTransientVariable(String name) {
+ if (transientVariables == null) return;
transientVariables.remove(name);
}
- Token getRootToken()
- {
+ Token getRootToken() {
return processInstance.getRootToken();
}
- /*
- * searches for the first token-variable-map for the given token and creates it on the root token if it doesn't exist.
+ /**
+ * searches for the first token-variable-map for the given token and creates it on the root token
+ * if it doesn't exist.
*/
- public TokenVariableMap getOrCreateTokenVariableMap(Token token)
- {
- if (token == null)
- {
+ public TokenVariableMap getOrCreateTokenVariableMap(Token token) {
+ if (token == null) {
throw new JbpmException("can't get variables for token 'null'");
}
// if the given token has a variable map
TokenVariableMap tokenVariableMap = null;
- if ((tokenVariableMaps != null) && (tokenVariableMaps.containsKey(token)))
- {
- tokenVariableMap = (TokenVariableMap)tokenVariableMaps.get(token);
+ if ((tokenVariableMaps != null) && (tokenVariableMaps.containsKey(token))) {
+ tokenVariableMap = (TokenVariableMap) tokenVariableMaps.get(token);
}
- else if (!token.isRoot())
- {
+ else if (!token.isRoot()) {
tokenVariableMap = getOrCreateTokenVariableMap(token.getParent());
}
- else
- {
+ else {
tokenVariableMap = createTokenVariableMap(token);
}
return tokenVariableMap;
}
- TokenVariableMap createTokenVariableMap(Token token)
- {
- if (tokenVariableMaps == null)
- {
+ TokenVariableMap createTokenVariableMap(Token token) {
+ if (tokenVariableMaps == null) {
tokenVariableMaps = new HashMap();
}
- TokenVariableMap tokenVariableMap = (TokenVariableMap)tokenVariableMaps.get(token);
- if (tokenVariableMap == null)
- {
+ TokenVariableMap tokenVariableMap = (TokenVariableMap) tokenVariableMaps.get(token);
+ if (tokenVariableMap == null) {
tokenVariableMap = new TokenVariableMap(token, this);
tokenVariableMaps.put(token, tokenVariableMap);
}
return tokenVariableMap;
}
- /*
- * looks for the first token-variable-map that is found up the token-parent hirarchy.
+ /**
+ * looks for the first token-variable-map that is found up the token-parent hierarchy.
*/
- public TokenVariableMap getTokenVariableMap(Token token)
- {
+ public TokenVariableMap getTokenVariableMap(Token token) {
TokenVariableMap tokenVariableMap = null;
- if (tokenVariableMaps != null)
- {
- if (tokenVariableMaps.containsKey(token))
- {
- tokenVariableMap = (TokenVariableMap)tokenVariableMaps.get(token);
+ if (tokenVariableMaps != null) {
+ if (tokenVariableMaps.containsKey(token)) {
+ tokenVariableMap = (TokenVariableMap) tokenVariableMaps.get(token);
}
- else if (!token.isRoot())
- {
+ else if (!token.isRoot()) {
tokenVariableMap = getTokenVariableMap(token.getParent());
}
}
return tokenVariableMap;
}
- public VariableInstance getVariableInstance(String name, Token token)
- {
+ public VariableInstance getVariableInstance(String name, Token token) {
VariableInstance variableInstance = null;
TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
- if (tokenVariableMap != null)
- {
+ if (tokenVariableMap != null) {
tokenVariableMap.getVariableInstances();
}
return variableInstance;
}
- public Map getTokenVariableMaps()
- {
+ public Map getTokenVariableMaps() {
return tokenVariableMaps;
}
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/Join.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/Join.java 2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/Join.java 2009-06-27 12:56:00 UTC (rev 5137)
@@ -95,28 +95,24 @@
public void execute(ExecutionContext executionContext) {
Token token = executionContext.getToken();
-
boolean isAbleToReactivateParent = token.isAbleToReactivateParent();
if (!token.hasEnded()) {
token.end(false);
}
- // if this token is not able to reactivate the parent,
+ // if this token is not able to reactivate the parent,
// we don't need to check anything
if (isAbleToReactivateParent) {
-
- // the token arrived in the join and can only reactivate
+ // the token arrived in the join and can only reactivate
// the parent once
token.setAbleToReactivateParent(false);
Token parentToken = token.getParent();
-
if (parentToken != null) {
-
JbpmContext jbpmContext = executionContext.getJbpmContext();
- Session session = (jbpmContext != null ? jbpmContext.getSession() : null);
- if (session != null) {
+ Session session;
+ if (jbpmContext != null && (session = jbpmContext.getSession()) != null) {
// obtain update lock by default (LockMode.UPGRADE)
LockMode lockMode = parentLockMode != null ? LockMode.parse(parentLockMode)
: LockMode.UPGRADE;
@@ -125,7 +121,7 @@
session.lock(parentToken, lockMode);
}
- boolean reactivateParent = true;
+ boolean reactivateParent;
// if this is a discriminator
if (isDiscriminator) {
@@ -133,57 +129,50 @@
// this must be the first token arriving, otherwise isAbleToReactivateParent()
// should have been false above.
reactivateParent = true;
-
- // if a fixed set of tokenNames is specified at design time...
}
+ // if a fixed set of tokenNames is specified at design time...
else if (tokenNames != null) {
// check reactivation on the basis of those tokenNames
reactivateParent = mustParentBeReactivated(parentToken, tokenNames.iterator());
-
- // if a script is specified
}
+ // if a script is specified
else if (script != null) {
-
// check if the script returns a collection or a boolean
Object result = null;
try {
result = script.eval(token);
}
catch (Exception e) {
- this.raiseException(e, executionContext);
+ raiseException(e, executionContext);
}
- // if the result is a collection
+ // if the result is a collection
if (result instanceof Collection) {
- // it must be a collection of tokenNames
+ // it must be a collection of tokenNames
Collection runtimeTokenNames = (Collection) result;
reactivateParent = mustParentBeReactivated(parentToken, runtimeTokenNames.iterator());
-
- // if it's a boolean...
}
+ // if it's a boolean...
else if (result instanceof Boolean) {
// the boolean specifies if the parent needs to be reactivated
reactivateParent = ((Boolean) result).booleanValue();
}
-
- // if a nOutOfM is specified
+ // otherwise
+ else {
+ // non-null result means the parent needs to be reactivated
+ reactivateParent = result != null;
+ }
}
+ // if a nOutOfM is specified
else if (nOutOfM != -1) {
-
int n = 0;
- // wheck how many tokens already arrived in the join
- Iterator iter = parentToken.getChildren().values().iterator();
- while (iter.hasNext()) {
+ // check how many tokens already arrived in the join
+ for (Iterator iter = parentToken.getChildren().values().iterator(); iter.hasNext();) {
Token concurrentToken = (Token) iter.next();
- if (this.equals(concurrentToken.getNode())) {
- n++;
- }
+ if (equals(concurrentToken.getNode())) n++;
}
- if (n < nOutOfM) {
- reactivateParent = false;
- }
-
- // if no configuration is specified..
+ reactivateParent = n >= nOutOfM;
}
+ // if no configuration is specified..
else {
// the default behaviour is to check all concurrent tokens and reactivate
// the parent if the last token arrives in the join
@@ -194,13 +183,11 @@
// if the parent token needs to be reactivated from this join node
if (reactivateParent) {
-
// write to all child tokens that the parent is already reactivated
- Iterator iter = parentToken.getChildren().values().iterator();
- while (iter.hasNext()) {
- ((Token) iter.next()).setAbleToReactivateParent(false);
+ for (Iterator iter = parentToken.getChildren().values().iterator(); iter.hasNext();) {
+ Token concurrentToken = (Token) iter.next();
+ concurrentToken.setAbleToReactivateParent(false);
}
-
// write to all child tokens that the parent is already reactivated
ExecutionContext parentContext = new ExecutionContext(parentToken);
leave(parentContext);
@@ -209,21 +196,16 @@
}
}
- public boolean mustParentBeReactivated(Token parentToken, Iterator childTokenNameIterator) {
- boolean reactivateParent = true;
- while ((childTokenNameIterator.hasNext()) && (reactivateParent)) {
- String concurrentTokenName = (String) childTokenNameIterator.next();
-
+ public boolean mustParentBeReactivated(Token parentToken, Iterator concurrentTokenNames) {
+ while (concurrentTokenNames.hasNext()) {
+ String concurrentTokenName = (String) concurrentTokenNames.next();
Token concurrentToken = parentToken.getChild(concurrentTokenName);
-
if (concurrentToken.isAbleToReactivateParent()) {
- log.debug("join will not yet reactivate parent: found concurrent token '"
- + concurrentToken
- + "'");
- reactivateParent = false;
+ log.debug("join will not reactivate parent yet, found concurrent " + concurrentToken);
+ return false;
}
}
- return reactivateParent;
+ return true;
}
public String getParentLockMode() {
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java 2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java 2009-06-27 12:56:00 UTC (rev 5137)
@@ -16,7 +16,6 @@
import org.jbpm.db.JobSession;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.job.Job;
-import org.jbpm.persistence.JbpmPersistenceException;
import org.jbpm.persistence.db.DbPersistenceService;
import org.jbpm.persistence.db.StaleObjectLogConfigurer;
@@ -151,16 +150,12 @@
acquiredJobs = jobsToLock;
log.debug("acquired lock on jobs: " + acquiredJobs);
}
- catch (JbpmPersistenceException e) {
- // if this is a stale state exception, keep it quiet
- if (DbPersistenceService.isStaleStateException(e)) {
- StaleObjectLogConfigurer.getStaleObjectExceptionsLog()
- .error("failed to acquire lock on jobs " + jobsToLock);
- acquiredJobs = Collections.EMPTY_LIST;
- }
- else {
- throw e;
- }
+ catch (RuntimeException e) {
+ if (!DbPersistenceService.isLockingException(e)) throw e;
+ // if this is a locking exception, keep it quiet
+ StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+ "failed to acquire lock on jobs " + jobsToLock);
+ acquiredJobs = Collections.EMPTY_LIST;
}
}
}
@@ -207,15 +202,11 @@
try {
jbpmContext.close();
}
- catch (JbpmPersistenceException e) {
- // if this is a stale state exception, keep it quiet
- if (DbPersistenceService.isStaleStateException(e)) {
- StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error("failed to complete job " +
- job);
- }
- else {
- throw e;
- }
+ catch (RuntimeException e) {
+ if (!DbPersistenceService.isLockingException(e)) throw e;
+ // if this is a locking exception, keep it quiet
+ StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+ "failed to complete job " + job);
}
}
}
@@ -241,16 +232,12 @@
try {
jbpmContext.close();
}
- catch (JbpmPersistenceException e) {
- // if this is a stale state exception, keep it quiet
- if (DbPersistenceService.isStaleStateException(e)) {
- StaleObjectLogConfigurer.getStaleObjectExceptionsLog()
- .error("failed to determine next due date for job executor thread " + threadName);
- nextDueDate = null;
- }
- else {
- throw e;
- }
+ catch (RuntimeException e) {
+ if (!DbPersistenceService.isLockingException(e)) throw e;
+ // if this is a locking exception, keep it quiet
+ StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+ "failed to determine next due date for job executor thread " + threadName);
+ nextDueDate = null;
}
}
return nextDueDate;
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java 2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java 2009-06-27 12:56:00 UTC (rev 5137)
@@ -11,7 +11,6 @@
import org.jbpm.JbpmContext;
import org.jbpm.db.JobSession;
import org.jbpm.job.Job;
-import org.jbpm.persistence.JbpmPersistenceException;
import org.jbpm.persistence.db.DbPersistenceService;
import org.jbpm.persistence.db.StaleObjectLogConfigurer;
@@ -47,16 +46,16 @@
currentLockMonitorInterval = lockMonitorInterval;
}
catch (RuntimeException e) {
- log.error("exception in lock monitor thread. waiting "
- + currentLockMonitorInterval
- + " milliseconds", e);
+ log.error("exception in lock monitor thread. waiting " +
+ currentLockMonitorInterval +
+ " milliseconds", e);
try {
sleep(currentLockMonitorInterval);
}
catch (InterruptedException ie) {
log.debug("delay after exception got interrupted", ie);
}
- // after an exception, double the current lock monitor interval to prevent
+ // after an exception, double the current lock monitor interval to prevent
// continuous exception generation when e.g. the db is unreachable
currentLockMonitorInterval <<= 1;
if (currentLockMonitorInterval > maxLockMonitorInterval || currentLockMonitorInterval < 0) {
@@ -92,15 +91,11 @@
try {
jbpmContext.close();
}
- catch (JbpmPersistenceException e) {
- // if this is a stale state exception, keep it quiet
- if (DbPersistenceService.isStaleStateException(e)) {
- StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
- "optimistic locking failed, could not unlock overdue jobs: " + overdueJobs);
- }
- else {
- throw e;
- }
+ catch (RuntimeException e) {
+ if (!DbPersistenceService.isLockingException(e)) throw e;
+ // if this is a locking exception, keep it quiet
+ StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+ "could not unlock overdue jobs: " + overdueJobs);
}
}
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java 2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java 2009-06-27 12:56:00 UTC (rev 5137)
@@ -22,6 +22,7 @@
package org.jbpm.persistence.db;
import java.sql.Connection;
+import java.sql.SQLException;
import javax.sql.DataSource;
@@ -32,6 +33,8 @@
import org.hibernate.SessionFactory;
import org.hibernate.StaleStateException;
import org.hibernate.Transaction;
+import org.hibernate.exception.LockAcquisitionException;
+
import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.db.ContextSession;
@@ -78,8 +81,8 @@
}
public SessionFactory getSessionFactory() {
- return session != null ? session.getSessionFactory() : persistenceServiceFactory
- .getSessionFactory();
+ return session != null ? session.getSessionFactory()
+ : persistenceServiceFactory.getSessionFactory();
}
public Session getSession() {
@@ -155,14 +158,14 @@
if (connection == null) {
if (persistenceServiceFactory.getDataSource() != null) {
try {
- log.debug("fetching jdbc connection from datasource");
+ log.debug("establishing connneciton to data source");
connection = persistenceServiceFactory.getDataSource().getConnection();
mustConnectionBeClosed = true;
}
- catch (Exception e) {
+ catch (SQLException e) {
// NOTE that Errors are not caught because that might halt the JVM
// and mask the original Error.
- throw new JbpmException("could not obtain connection from datasource", e);
+ throw new JbpmPersistenceException("connection to data source failed", e);
}
}
else {
@@ -172,9 +175,9 @@
}
if (session != null) {
connection = session.connection();
- log.debug("fetched "
- + connection
- + " from hibernate session, client is responsible for closing it!");
+ log.debug("fetched " +
+ connection +
+ " from hibernate session, client is responsible for closing it!");
mustConnectionBeClosed = false;
}
}
@@ -226,15 +229,8 @@
mustSessionBeFlushed = false; // commit does a flush anyway
transaction.commit();
}
- catch (Exception e) {
- if (isStaleStateException(e)) {
- log.info("problem committing transaction: optimistic locking failed");
- StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
- "optimistic locking failed while committing " + transaction, e);
- }
- else {
- log.error("transaction commit failed", e);
- }
+ catch (HibernateException e) {
+ // avoid log and throw antipattern
return e;
}
return null;
@@ -247,8 +243,8 @@
mustSessionBeFlushed = false;
transaction.rollback();
}
- catch (Exception e) {
- log.error("transaction rollback failed", e);
+ catch (HibernateException e) {
+ // avoid log and throw antipattern
return e;
}
return null;
@@ -260,15 +256,8 @@
log.debug("flushing " + session);
session.flush();
}
- catch (Exception e) {
- if (isStaleStateException(e)) {
- log.info("problem flushing session: optimistic locking failed");
- StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
- "optimistic locking failed while flushing " + session, e);
- }
- else {
- log.error("hibernate flush failed", e);
- }
+ catch (HibernateException e) {
+ // avoid log and throw antipatternf
return e;
}
}
@@ -277,17 +266,18 @@
private Exception closeSession() {
if (mustSessionBeClosed) {
- try {
- if (session.isOpen()) {
+ if (session.isOpen()) {
+ try {
log.debug("closing hibernate session");
session.close();
}
- else {
- log.warn("hibernate session was already closed");
+ catch (HibernateException e) {
+ // avoid log and throw antipattern
+ return e;
}
}
- catch (Exception e) {
- return e;
+ else {
+ log.warn("hibernate session was already closed");
}
}
return null;
@@ -295,18 +285,18 @@
private Exception closeConnection() {
if (mustConnectionBeClosed) {
- try {
- if (connection != null) {
+ if (connection != null) {
+ try {
log.debug("closing jdbc connection");
connection.close();
}
- else {
- log.warn("jdbc connection was already closed");
+ catch (SQLException e) {
+ // avoid log and throw antipattern
+ return e;
}
}
- catch (Exception e) {
- log.error("hibernate session close failed", e);
- return e;
+ else {
+ log.warn("jdbc connection was already closed");
}
}
return null;
@@ -316,7 +306,7 @@
try {
getSession().save(object);
}
- catch (Exception e) {
+ catch (HibernateException e) {
// NOTE that Errors are not caught because that might halt the JVM
// and mask the original Error.
throw new JbpmPersistenceException("couldn't assign id to " + object, e);
@@ -514,9 +504,9 @@
return false;
}
- public static boolean isStaleStateException(Exception exception) {
+ public static boolean isLockingException(Exception exception) {
for (Throwable t = exception; t != null; t = t.getCause()) {
- if (t instanceof StaleStateException) return true;
+ if (t instanceof StaleStateException || t instanceof LockAcquisitionException) return true;
}
return false;
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/jta/JtaDbPersistenceService.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/jta/JtaDbPersistenceService.java 2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/jta/JtaDbPersistenceService.java 2009-06-27 12:56:00 UTC (rev 5137)
@@ -21,6 +21,10 @@
*/
package org.jbpm.persistence.jta;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
@@ -29,9 +33,9 @@
import org.apache.commons.logging.LogFactory;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.util.JTAHelper;
+
import org.jbpm.JbpmException;
import org.jbpm.persistence.db.DbPersistenceService;
-import org.jbpm.persistence.db.StaleObjectLogConfigurer;
public class JtaDbPersistenceService extends DbPersistenceService {
@@ -59,8 +63,8 @@
}
protected boolean isTransactionRollbackOnly() {
- return super.isTransactionRollbackOnly()
- || JTAHelper.isMarkedForRollback(getTransactionStatus());
+ return super.isTransactionRollbackOnly() ||
+ JTAHelper.isMarkedForRollback(getTransactionStatus());
}
public void beginTransaction() {
@@ -70,7 +74,10 @@
transaction = jtaFactory.getUserTransaction();
transaction.begin();
}
- catch (Exception e) {
+ catch (NotSupportedException e) {
+ throw new JbpmException("transaction is already in course", e);
+ }
+ catch (SystemException e) {
throw new JbpmException("transaction begin failed", e);
}
}
@@ -91,21 +98,19 @@
transaction.commit();
return null;
}
- catch (Exception e) {
- if (isStaleStateException(e)) {
- log.debug("optimistic locking failed, could not commit " + transaction);
- StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
- "optimistic locking failed, could not commit " + transaction, e);
- }
- else {
- // Switched to debug because either handle OR log
- // an exception is best practice, not both!
- // Example: Clustered JobExecutor may have
- // Exceptions which should be kept quiet
- log.debug("transaction commit failed", e);
- }
+ // avoid log and throw antipattern
+ catch (RollbackException e) {
return e;
}
+ catch (HeuristicMixedException e) {
+ return e;
+ }
+ catch (HeuristicRollbackException e) {
+ return e;
+ }
+ catch (SystemException e) {
+ return e;
+ }
}
protected Exception rollback() {
@@ -114,12 +119,8 @@
transaction.rollback();
return null;
}
- catch (Exception e) {
- // Switched to debug because either handle OR log
- // an exception is best practice, not both!
- // Example: Clustered JobExecutor may have
- // Exceptions which should be kept quiet
- log.debug("transaction rollback failed", e);
+ catch (SystemException e) {
+ // avoid log and throw antipattern
return e;
}
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java 2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java 2009-06-27 12:56:00 UTC (rev 5137)
@@ -33,11 +33,9 @@
import org.apache.commons.logging.LogFactory;
import org.jbpm.JbpmContext;
-import org.jbpm.JbpmException;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.logging.LoggingService;
import org.jbpm.msg.MessageService;
-import org.jbpm.persistence.JbpmPersistenceException;
import org.jbpm.persistence.PersistenceService;
import org.jbpm.persistence.db.DbPersistenceService;
import org.jbpm.persistence.db.StaleObjectLogConfigurer;
@@ -236,45 +234,36 @@
}
public void close() {
- if (services != null) {
- Exception firstException = null;
- for (Iterator iter = serviceNames.iterator(); iter.hasNext();) {
- String serviceName = (String) iter.next();
- Service service = (Service) services.get(serviceName);
- if (service != null) {
- try {
- log.debug("closing service '" + serviceName + "': " + service);
- service.close();
+ if (services == null) return;
+
+ RuntimeException firstException = null;
+ for (Iterator iter = serviceNames.iterator(); iter.hasNext();) {
+ String serviceName = (String) iter.next();
+ Service service = (Service) services.get(serviceName);
+ if (service == null) continue;
+
+ try {
+ log.debug("closing '" + serviceName + "' service");
+ service.close();
+ }
+ catch (RuntimeException e) {
+ if (firstException == null) {
+ firstException = e;
+ }
+ else {
+ // if this is a locking exception, keep it quiet
+ if (DbPersistenceService.isLockingException(e)) {
+ StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+ "problem closing '" + serviceName + "' service", e);
}
- catch (JbpmPersistenceException e) {
- // if this is a stale state exception, keep it quiet
- if (DbPersistenceService.isStaleStateException(e)) {
- log.info("optimistic locking failed, could not close service: " + serviceName);
- StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
- "optimistic locking failed, could not close service: " + serviceName, e);
- }
- else {
- log.error("problem closing service '" + serviceName + "'", e);
- }
- if (firstException == null) {
- firstException = e;
- }
+ else {
+ log.error("problem closing '" + serviceName + "' service", e);
}
- catch (Exception e) {
- // NOTE that Error's are not caught because that might halt the JVM
- // and mask the original Error.
- log.error("problem closing service '" + serviceName + "'", e);
- if (firstException == null) {
- firstException = e;
- }
- }
}
}
- if (firstException != null) {
- throw firstException instanceof JbpmException ? (JbpmException) firstException
- : new JbpmException("problem closing services", firstException);
- }
}
+
+ if (firstException != null) throw firstException;
}
public static void assignId(Object object) {
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/perf/SimplePerformanceTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/perf/SimplePerformanceTest.java 2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/perf/SimplePerformanceTest.java 2009-06-27 12:56:00 UTC (rev 5137)
@@ -22,11 +22,8 @@
package org.jbpm.perf;
import org.jbpm.db.AbstractDbTestCase;
-import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.def.ProcessDefinition;
-import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.ProcessInstance;
-import org.jbpm.util.Semaphore;
/**
* This test creates a number of process instances. Every instance has a call to an ActionHandler.
@@ -41,86 +38,52 @@
private static final int WARMUP_INSTANCES = 100;
private static final int MEASUREMENT_INSTANCES = 1000;
+ private static final long TIMEOUT = 5 * 60 * 1000;
- private static final Semaphore signalLight = new Semaphore(0);
-
private ProcessDefinition processDefinition;
protected void setUp() throws Exception {
super.setUp();
processDefinition = ProcessDefinition.parseXmlString("<process-definition name='perf'>"
- + " <event type='process-start'>"
- + " <action class='"
- + AsyncSignalAction.class.getName()
- + "' async='true'/>"
- + " </event>"
+ " <start-state name='start'>"
+ " <transition to='end'/>"
+ " </start-state>"
- + " <end-state name='end'/>"
+ + " <end-state async='true' name='end'/>"
+ "</process-definition>");
jbpmContext.deployProcessDefinition(processDefinition);
-
- newTransaction();
- startJobExecutor();
}
protected void tearDown() throws Exception {
- stopJobExecutor();
-
- newTransaction();
jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
-
super.tearDown();
}
public void testAsyncCall() {
- // Won't Fix [JBPM-2043] Performance test coverage
- if (getHibernateDialect().indexOf("HSQL") != -1) return;
-
launchProcessInstances(WARMUP_INSTANCES);
long startTime = System.currentTimeMillis();
launchProcessInstances(MEASUREMENT_INSTANCES);
long duration = (System.currentTimeMillis() - startTime) / 1000;
- System.out.println("=== Test finished processing "
- + MEASUREMENT_INSTANCES
- + " instances in "
- + duration
- + " seconds ===");
- System.out.println("=== This is "
- + (MEASUREMENT_INSTANCES / duration)
- + " instances per second ===");
+ System.out.println("=== Test finished processing " +
+ MEASUREMENT_INSTANCES +
+ " instances in " +
+ duration +
+ " seconds ===");
+ System.out.println("=== This is " +
+ (MEASUREMENT_INSTANCES / duration) +
+ " instances per second ===");
}
private void launchProcessInstances(int count) {
for (int i = 0; i < count; i++) {
- ProcessInstance pi = new ProcessInstance(processDefinition);
- jbpmContext.save(pi);
newTransaction();
+ ProcessInstance processInstance = new ProcessInstance(processDefinition);
+ processInstance.signal();
+ jbpmContext.save(processInstance);
}
- commitAndCloseSession();
- try {
- signalLight.acquire(count);
- }
- catch (InterruptedException e) {
- fail(getName() + " got interrupted while waiting for process instances to end");
- }
- finally {
- beginSessionTransaction();
- }
+ processJobs(TIMEOUT);
}
-
- public static class AsyncSignalAction implements ActionHandler {
-
- private static final long serialVersionUID = -8617329370138396271L;
-
- public void execute(final ExecutionContext executionContext) throws Exception {
- executionContext.leaveNode();
- signalLight.release();
- }
- }
}
More information about the jbpm-commits
mailing list