[jbpm-commits] JBoss JBPM SVN: r5069 - in jbpm4/trunk/modules/test-concurrent/src: test/java/org/jbpm/test/concurrent and 1 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Fri Jun 19 13:26:38 EDT 2009
Author: jbarrez
Date: 2009-06-19 13:26:38 -0400 (Fri, 19 Jun 2009)
New Revision: 5069
Added:
jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/CommandExecutionSynchronization.java
jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/SynchronizableCommandExecutor.java
jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/AsyncForkTest.java
Removed:
jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulator.java
jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorPool.java
jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorSynchronization.java
Modified:
jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/ConcurrentJbpmTestCase.java
jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/OptimisticLockTestGround.java
jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/TimerVsSignalConcurrencyTest.java
jbpm4/trunk/modules/test-concurrent/src/test/resources/jbpm.cfg.xml
Log:
Commit intermediate work on concurrent testing (work in progress - doesnt work yet)
Copied: jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/CommandExecutionSynchronization.java (from rev 5049, jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorSynchronization.java)
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/CommandExecutionSynchronization.java (rev 0)
+++ jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/CommandExecutionSynchronization.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+/**
+ *
+ */
+package org.jbpm.test.concurrent;
+
+/**
+ * Implementations can extend this class to add logic to sync points of the
+ * {@link SynchronizableCommandExecutor}.
+ *
+ * @author Joram Barrez
+ */
+public abstract class CommandExecutionSynchronization {
+
+ public void beforeTransactionStarts() { }
+
+ public void afterTransactionStarted() { }
+
+ public void beforeExecution() { }
+
+ public void afterExecution() { }
+
+ public void beforeTransactionDone() { }
+
+ public void afterTransactionDone() { }
+
+}
Modified: jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/ConcurrentJbpmTestCase.java
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/ConcurrentJbpmTestCase.java 2009-06-19 15:53:46 UTC (rev 5068)
+++ jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/ConcurrentJbpmTestCase.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -39,37 +39,7 @@
protected void setUp() throws Exception {
super.setUp();
- this.environmentFactory = (EnvironmentFactory) processEngine; // Is there a better way to do this?
+ this.environmentFactory = (EnvironmentFactory) processEngine;
}
-
- protected class OffloadThread extends Thread {
-
- private ThreadCallback threadCallback;
-
- private Exception exception;
-
- public OffloadThread(ThreadCallback threadCallback) {
- this.threadCallback = threadCallback;
- }
- public void run() {
- try {
- threadCallback.executeInThread();
- } catch (Exception e) {
- this.exception = e;
- }
- }
-
- public Exception getException() {
- return exception;
- }
-
- }
-
- protected interface ThreadCallback {
-
- void executeInThread();
-
- }
-
}
Deleted: jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulator.java
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulator.java 2009-06-19 15:53:46 UTC (rev 5068)
+++ jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulator.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -1,302 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-/**
- *
- */
-package org.jbpm.test.concurrent;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.BrokenBarrierException;
-import java.util.concurrent.CyclicBarrier;
-
-import org.jbpm.api.env.Environment;
-import org.jbpm.api.env.EnvironmentFactory;
-import org.jbpm.api.job.Job;
-import org.jbpm.pvm.internal.cmd.ExecuteJobCmd;
-import org.jbpm.pvm.internal.tx.StandardTransaction;
-
-/**
- * Emulates the JobExecutorThread by executing the ExecuteJobCmd in
- * a dedicated thread.
- *
- * Has several sync points available (see {@link JobExecutorEmulatorSynchronization}):
- * - before/after transaction is started
- * - before/after job execution
- * - before/after transaction is done (ie commit)
- *
- * TODO: implement transaction sync, now only sync on job execution is done - waiting until use case passes by
- *
- * @author Joram Barrez
- */
-public class JobExecutorEmulator extends Thread {
-
- /** Used to create environment blocks */
- private EnvironmentFactory environmentFactory;
-
- /** The database id of the job that is executed by this JobExecutorEmulator */
- private Long jobId;
-
- /**
- * If an exception occurs in a thread that is not the JUnit thread, then
- * the JUnit thread will never notice this. The solution is to catch the
- * exception and store it in this field, so the JUnit thread can check
- * if there were any exceptions when executing the job.
- */
- private Exception exception;
-
- /** Indicates if the thread must be blocked (ie this.wait() must be called) */
- private boolean threadBlocked;
-
- /**
- * List of synchronizations that will be called on specific point in the
- * execution of this thread.
- */
- private List<JobExecutorEmulatorSynchronization> synchronizations;
-
- /* SYNC PRIMITIVES */
-
- /** Sync point when the job is executed */
- private CyclicBarrier afterJobExecutionBarrier;
-
- private List<String> afterJobExecutionSyncThreads;
-
- /** Sync point before the job is executed */
- private CyclicBarrier beforeJobExecutionBarrier;
-
- private List<String> beforeJobExecutionSyncThreads;
-
- /**
- * Constructor.
- *
- * @param job The job that must be executred by this emulator.
- */
- public JobExecutorEmulator(EnvironmentFactory environmentFactory, Job job) {
- this.environmentFactory = environmentFactory;
- this.jobId = job.getDbid();
- this.threadBlocked = false;
-
- this.synchronizations = new ArrayList<JobExecutorEmulatorSynchronization>();
- synchronizations.add(new DefaultSynchronization());
- }
-
- public void run() {
-
- Environment environment = environmentFactory.openEnvironment();
- StandardTransaction standardTransaction = environment.get(StandardTransaction.class);
- standardTransaction.begin();
-
- try {
-
- handleBeforeJobExecutionSynchronizations();
- ExecuteJobCmd executeJobCmd = new ExecuteJobCmd(jobId);
- executeJobCmd.execute(environment);
- handleAfterJobExecutionSynchronizations(); // Sync point: after job execution
-
- } catch (Exception e) {
-
- standardTransaction.setRollbackOnly();
- this.exception = e;
-
- } finally {
-
- if (standardTransaction.isRollbackOnly()) {
- exception = new Exception("Transaction was rollbacked due to an exception");
- }
-
- try {
- standardTransaction.complete();
- } catch (Exception e) {
-
- }
-
- }
- environment.close();
- }
-
- /**
- * Executes all synchronizations that must be executed before the job is executed
- */
- private void handleBeforeJobExecutionSynchronizations() {
- for (JobExecutorEmulatorSynchronization synchronization : synchronizations) {
- synchronization.beforeJobExecution();
- }
- }
-
- /**
- * Executes all synchronizations that must be executed when the job is executed
- */
- private void handleAfterJobExecutionSynchronizations() {
- for (JobExecutorEmulatorSynchronization synchronization : synchronizations) {
- synchronization.afterJobExecution();
- }
- }
-
- /**
- * Unit tests that use this class can use this method to synchronize
- * when the job just has been executed.
- *
- * @param blockJobExecutor If true, the jobExecutor will be halted
- * when leaving the synchronisation point
- */
- public void waitUntilJobExecuted(boolean blockJobExecutor) {
- if (afterJobExecutionBarrier != null) {
- try {
- threadBlocked = blockJobExecutor;
- afterJobExecutionBarrier.await();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (BrokenBarrierException e) {
- e.printStackTrace();
- }
- }
- }
-
- public JobExecutorEmulator synchroniseAfterJobExecution(String threadName) {
- if (isAlive()) {
- throw new RuntimeException("Cannot set synchronization point once the JobExecutorEmulator has been started");
- }
-
- if (afterJobExecutionSyncThreads == null) {
- afterJobExecutionSyncThreads = new ArrayList<String>();
- }
-
- if (afterJobExecutionBarrier == null ) {
- afterJobExecutionBarrier = new CyclicBarrier(2);
- } else {
- afterJobExecutionBarrier = new CyclicBarrier(afterJobExecutionBarrier.getParties() + 1);
- }
-
- return this;
- }
-
- public JobExecutorEmulator synchroniseBeforeJobExecution(String threadName) {
- if (isAlive()) {
- throw new RuntimeException("Cannot set synchronization point once the JobExecutorEmulator has been started");
- }
-
- if (beforeJobExecutionBarrier == null) {
- beforeJobExecutionSyncThreads = new ArrayList<String>();
- }
-
- if (beforeJobExecutionBarrier == null ) {
- beforeJobExecutionBarrier = new CyclicBarrier(2);
- } else {
- beforeJobExecutionBarrier = new CyclicBarrier(beforeJobExecutionBarrier.getParties() + 1);
- }
-
- return this;
- }
-
- /**
- * Helper method: check if the flag 'threadBlocked' has been raised.
- * If so, this thread will block until it is notified again.
- */
- private void blockIfNeeded() {
- if (threadBlocked) {
- synchronized (this) {
- try {
- threadBlocked = false;
- wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- /**
- * Unit tests can use this method to proceed a halted JobExecutorEmulator.
- * (ie this means that the wait() was called on this thread in the past).
- */
- public void goOn() {
- synchronized (this) {
- notify();
- };
- }
-
- /**
- * Adds a custom synchronization to the JobExecutorEmulator.
- */
- public void addSynchronization(JobExecutorEmulatorSynchronization synchronization) {
- synchronizations.add(synchronization);
- }
-
- /* GETTERS AND SETTERS */
-
- public Exception getException() {
- return exception;
- }
-
- public boolean isBlockThread() {
- return threadBlocked;
- }
-
- public void setBlockThread(boolean blockThread) {
- this.threadBlocked = blockThread;
- }
-
- public void setAfterJobExecutionBarrier(CyclicBarrier afterJobExecutionBarrier) {
- this.afterJobExecutionBarrier = afterJobExecutionBarrier;
- }
-
- public void setBeforeJobExecutionBarrier(CyclicBarrier beforeJobExecutionBarrier) {
- this.beforeJobExecutionBarrier = beforeJobExecutionBarrier;
- }
-
- /**
- * Default synchronization, executed by all JobExecutorEmulators.
- * The default logic will synchronize at every sync point (ie barrier)
- * which is not null and will check if any external caller has raised
- * the 'threadBlocked' flag.
- */
- private class DefaultSynchronization extends JobExecutorEmulatorSynchronization {
-
- public void afterJobExecution() {;
- if (afterJobExecutionBarrier != null) {
- try {
- afterJobExecutionBarrier.await();
- blockIfNeeded();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (BrokenBarrierException e) {
- e.printStackTrace();
- }
- }
- }
-
- public void beforeJobExecution() {;
- if (beforeJobExecutionBarrier != null) {
- try {
- beforeJobExecutionBarrier.await();
- blockIfNeeded();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (BrokenBarrierException e) {
- e.printStackTrace();
- }
- }
- }
-
- }
-
-}
Deleted: jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorPool.java
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorPool.java 2009-06-19 15:53:46 UTC (rev 5068)
+++ jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorPool.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -1,53 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-/**
- *
- */
-package org.jbpm.test.concurrent;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.jbpm.api.env.EnvironmentFactory;
-import org.jbpm.api.job.Job;
-
-
-/**
- * @author Joram Barrez
- */
-public class JobExecutorEmulatorPool {
-
- private EnvironmentFactory environmentFactory;
-
- private List<JobExecutorEmulator> jobExecutorEmulators;
-
- public JobExecutorEmulatorPool(EnvironmentFactory environmentFactory) {
- this.environmentFactory = environmentFactory;
- this.jobExecutorEmulators = new ArrayList<JobExecutorEmulator>();
- }
-
- public void emulateJobExecution(Collection<Job> jobs) {
-
- }
-
-}
Deleted: jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorSynchronization.java
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorSynchronization.java 2009-06-19 15:53:46 UTC (rev 5068)
+++ jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulatorSynchronization.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -1,47 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-/**
- *
- */
-package org.jbpm.test.concurrent;
-
-/**
- * Implementations can extend this class to add logic to sync points of the
- * {@link JobExecutorEmulator}.
- *
- * @author Joram Barrez
- */
-public abstract class JobExecutorEmulatorSynchronization {
-
- public void beforeTransactionStarts() { }
-
- public void afterTransactionStarted() { }
-
- public void beforeJobExecution() { }
-
- public void afterJobExecution() { }
-
- public void beforeTransactionDone() { }
-
- public void afterTransactionDone() { }
-
-}
Copied: jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/SynchronizableCommandExecutor.java (from rev 5049, jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/JobExecutorEmulator.java)
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/SynchronizableCommandExecutor.java (rev 0)
+++ jbpm4/trunk/modules/test-concurrent/src/main/java/org/jbpm/test/concurrent/SynchronizableCommandExecutor.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -0,0 +1,330 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+/**
+ *
+ */
+package org.jbpm.test.concurrent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+import org.jbpm.api.cmd.Command;
+import org.jbpm.api.env.Environment;
+import org.jbpm.api.env.EnvironmentFactory;
+import org.jbpm.api.job.Job;
+import org.jbpm.pvm.internal.cmd.ExecuteJobCmd;
+import org.jbpm.pvm.internal.tx.StandardTransaction;
+
+/**
+ * Executes a given command in a separate thread.
+ *
+ * Has several sync points available (see {@link CommandExecutionSynchronization}):
+ * - before/after transaction is started
+ * - before/after job execution
+ * - before/after transaction is done (ie commit)
+ *
+ * TODO: implement transaction sync, now only sync on job execution is done - waiting until use case passes by
+ *
+ * @author Joram Barrez
+ */
+public class SynchronizableCommandExecutor extends Thread {
+
+ /** Used to create environment blocks */
+ private EnvironmentFactory environmentFactory;
+
+ /** The database id of the job that will be executed */
+ private Long jobId;
+
+ /** The command that will be executed */
+ private Command command;
+
+ /**
+ * If an exception occurs in a thread that is not the JUnit thread, then
+ * the JUnit thread will never notice this. The solution is to catch the
+ * exception and store it in this field, so the JUnit thread can check
+ * if there were any exceptions when executing the job.
+ */
+ private Exception exception;
+
+ /** Indicates if the thread must be blocked (ie this.wait() must be called) */
+ private boolean threadBlocked;
+
+ /**
+ * List of synchronizations that will be called on specific point in the
+ * execution of this thread.
+ */
+ private List<CommandExecutionSynchronization> synchronizations;
+
+ /* SYNC PRIMITIVES */
+
+ private CyclicBarrier afterExecutionBarrier;
+
+ private CyclicBarrier beforeExecutionBarrier;
+
+ /**
+ * Constructor to be used when the thread must execute a job
+ */
+ public SynchronizableCommandExecutor(EnvironmentFactory environmentFactory, Job job) {
+ this.environmentFactory = environmentFactory;
+ this.jobId = job.getDbid();
+ this.threadBlocked = false;
+
+ this.synchronizations = new ArrayList<CommandExecutionSynchronization>();
+ synchronizations.add(new DefaultSynchronization());
+ }
+
+ /**
+ * Constructor to be used when the thread must execute a command
+ */
+ public SynchronizableCommandExecutor(EnvironmentFactory environmentFactory, Command command) {
+ this.environmentFactory = environmentFactory;
+ this.command = command;
+ this.threadBlocked = false;
+
+ this.synchronizations = new ArrayList<CommandExecutionSynchronization>();
+ synchronizations.add(new DefaultSynchronization());
+ }
+
+ public void run() {
+
+ Environment environment = environmentFactory.openEnvironment();
+ StandardTransaction standardTransaction = environment.get(StandardTransaction.class);
+ standardTransaction.begin();
+
+ try {
+
+ handleBeforeExecutionSynchronizations();
+
+ if (jobId != null) {
+ ExecuteJobCmd executeJobCmd = new ExecuteJobCmd(jobId);
+ executeJobCmd.execute(environment);
+ }
+
+ if (command != null) {
+ command.execute(environment);
+ }
+
+ handleAfterExecutionSynchronizations();
+
+ } catch (Exception e) {
+ standardTransaction.setRollbackOnly();
+ this.exception = e;
+
+ } finally {
+
+ try {
+ standardTransaction.complete();
+ } catch (Exception e) {
+ this.exception = e;
+ }
+
+ }
+ environment.close();
+ }
+
+ /**
+ * Executes all synchronizations that must be executed before the job is executed
+ */
+ private void handleBeforeExecutionSynchronizations() {
+ for (CommandExecutionSynchronization synchronization : synchronizations) {
+ synchronization.beforeExecution();
+ }
+ }
+
+ /**
+ * Executes all synchronizations that must be executed when the job is executed
+ */
+ private void handleAfterExecutionSynchronizations() {
+ for (CommandExecutionSynchronization synchronization : synchronizations) {
+ synchronization.afterExecution();
+ }
+ }
+
+ /**
+ * Unit tests that use this class can use this method to synchronize
+ * when the job just has been executed.
+ *
+ * @param blockJobExecutor If true, the jobExecutor will be halted
+ * when leaving the synchronisation point
+ */
+ public void waitUntilExecutionFinished(boolean blockJobExecutor) {
+ if (afterExecutionBarrier != null) {
+ try {
+ threadBlocked = blockJobExecutor;
+ afterExecutionBarrier.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (BrokenBarrierException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public SynchronizableCommandExecutor synchroniseAfterExecution() {
+ if (isAlive()) {
+ throw new RuntimeException("Cannot set synchronization point once the thread has been started");
+ }
+
+ if (afterExecutionBarrier == null ) {
+ afterExecutionBarrier = new CyclicBarrier(2);
+ } else {
+ afterExecutionBarrier = new CyclicBarrier(afterExecutionBarrier.getParties() + 1);
+ }
+
+ return this;
+ }
+
+ public SynchronizableCommandExecutor synchroniseAfterExecution(SynchronizableCommandExecutor otherExecutor) {
+ if (this.isAlive() || otherExecutor.isAlive()) {
+ throw new RuntimeException("Cannot set synchronization point once the thread has been started");
+ }
+
+ int threadsInvolved = 0;
+ if (afterExecutionBarrier != null) {
+ threadsInvolved += afterExecutionBarrier.getParties();
+ } else {
+ threadsInvolved++;
+ }
+
+ if (otherExecutor.afterExecutionBarrier != null) {
+ threadsInvolved += otherExecutor.afterExecutionBarrier.getParties();
+ } else {
+ threadsInvolved++;
+ }
+
+ this.afterExecutionBarrier = new CyclicBarrier(threadsInvolved);
+ otherExecutor.afterExecutionBarrier = this.afterExecutionBarrier;
+
+ return this;
+ }
+
+ public SynchronizableCommandExecutor synchroniseBeforeExecution() {
+ if (isAlive()) {
+ throw new RuntimeException("Cannot set synchronization point once the JobExecutorEmulator has been started");
+ }
+
+ if (beforeExecutionBarrier == null ) {
+ beforeExecutionBarrier = new CyclicBarrier(2);
+ } else {
+ beforeExecutionBarrier = new CyclicBarrier(beforeExecutionBarrier.getParties() + 1);
+ }
+
+ return this;
+ }
+
+ /**
+ * Helper method: check if the flag 'threadBlocked' has been raised.
+ * If so, this thread will block until it is notified again.
+ */
+ private void blockIfNeeded() {
+ if (threadBlocked) {
+ synchronized (this) {
+ try {
+ threadBlocked = false;
+ wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * Unit tests can use this method to proceed a halted JobExecutorEmulator.
+ * (ie this means that the wait() was called on this thread in the past).
+ */
+ public void goOn() {
+ synchronized (this) {
+ notify();
+ };
+ }
+
+ /**
+ * Adds a custom synchronization to the JobExecutorEmulator.
+ */
+ public void addSynchronization(CommandExecutionSynchronization synchronization) {
+ synchronizations.add(synchronization);
+ }
+
+ /* GETTERS AND SETTERS */
+
+ public Exception getException() {
+ return exception;
+ }
+
+ public boolean isBlockThread() {
+ return threadBlocked;
+ }
+
+ public void setBlockThread(boolean blockThread) {
+ this.threadBlocked = blockThread;
+ }
+
+ public void setAfterExecutionBarrier(CyclicBarrier afterExecutionBarrier) {
+ this.afterExecutionBarrier = afterExecutionBarrier;
+ }
+
+ public void setBeforeExecutionBarrier(CyclicBarrier beforeExecutionBarrier) {
+ this.beforeExecutionBarrier = beforeExecutionBarrier;
+ }
+
+ /**
+ * Default synchronization, executed by all threads.
+ * The default logic will synchronize at every sync point (ie barrier)
+ * which is not null and will check if any external caller has raised
+ * the 'threadBlocked' flag.
+ */
+ private class DefaultSynchronization extends CommandExecutionSynchronization {
+
+ public void afterExecution() {
+
+ if (afterExecutionBarrier != null) {
+ try {
+ afterExecutionBarrier.await();
+ blockIfNeeded();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (BrokenBarrierException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void beforeExecution() {
+
+ if (beforeExecutionBarrier != null) {
+ try {
+ beforeExecutionBarrier.await();
+ blockIfNeeded();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (BrokenBarrierException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ }
+
+}
Added: jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/AsyncForkTest.java
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/AsyncForkTest.java (rev 0)
+++ jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/AsyncForkTest.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -0,0 +1,58 @@
+package org.jbpm.test.concurrent;
+
+import java.util.List;
+
+import org.hibernate.StaleStateException;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.job.Job;
+
+
+public class AsyncForkTest extends ConcurrentJbpmTestCase {
+
+ public void testAsyncForkNoOptimisticLockingFailure() {
+ deployJpdlXmlString(
+ "<process name='asyncFork'>" +
+ " <start>" +
+ " <transition to='theFork' />" +
+ " </start>" +
+ " <fork name='theFork'>" +
+ " <on event='end' continue='async' />" +
+ " <transition to='pathA' />" +
+ " <transition to='pathB' />" +
+ " </fork>" +
+ " <custom name='pathA' class='org.jbpm.test.concurrent.PassThroughActivity' >" +
+ " <transition to='theJoin' />" +
+ " </custom>" +
+ " <custom name='pathB' class='org.jbpm.test.concurrent.PassThroughActivity' >" +
+ " <transition to='theJoin' />" +
+ " </custom>" +
+ " <join name='theJoin'>" +
+ " <transition to='test' />" +
+ " </join>" +
+ " <state name='test' >" +
+ " <transition to='end' /> " +
+ " </state>" +
+ " <end name='end' />" +
+ "</process>"
+ );
+
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("asyncFork");
+ final List<Job> jobs = managementService.createJobQuery().processInstanceId(processInstance.getId()).list();
+ assertEquals(2, jobs.size());
+
+ SynchronizableCommandExecutor executor1 = new SynchronizableCommandExecutor(environmentFactory, jobs.get(0));
+ SynchronizableCommandExecutor executor2 = new SynchronizableCommandExecutor(environmentFactory, jobs.get(1));
+
+ executor1.synchroniseAfterExecution(executor2);
+ executor1.synchroniseAfterExecution();
+
+ executor1.start();
+ executor2.start();
+
+ if (executor1.getException() instanceof StaleStateException
+ || executor2.getException() instanceof StaleStateException) {
+ fail("A StaleStaeException was thrown, altough this shouldn't happen");
+ }
+ }
+
+}
Property changes on: jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/AsyncForkTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/OptimisticLockTestGround.java
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/OptimisticLockTestGround.java 2009-06-19 15:53:46 UTC (rev 5068)
+++ jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/OptimisticLockTestGround.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -41,8 +41,7 @@
* Class to test different approaches to the concurrency problem.
*
* Doesnt work anymore, but dont delete yet, I need some stuff in here for later!
- *
- * @author Joram Barrez
+ * * @author Joram Barrez
*/
public class OptimisticLockTestGround extends JbpmTestCase {
Modified: jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/TimerVsSignalConcurrencyTest.java
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/TimerVsSignalConcurrencyTest.java 2009-06-19 15:53:46 UTC (rev 5068)
+++ jbpm4/trunk/modules/test-concurrent/src/test/java/org/jbpm/test/concurrent/TimerVsSignalConcurrencyTest.java 2009-06-19 17:26:38 UTC (rev 5069)
@@ -25,13 +25,12 @@
package org.jbpm.test.concurrent;
import java.util.List;
-import java.util.concurrent.CyclicBarrier;
+import org.hibernate.StaleStateException;
import org.jbpm.api.Execution;
import org.jbpm.api.ProcessInstance;
-import org.jbpm.api.env.EnvironmentFactory;
import org.jbpm.api.job.Job;
-import org.jbpm.test.JbpmTestCase;
+import org.jbpm.pvm.internal.cmd.SignalCmd;
/**
@@ -60,56 +59,35 @@
final List<Job> jobs = managementService.createJobQuery().processInstanceId(processInstance.getId()).list();
assertEquals(1, jobs.size());
- JobExecutorEmulator jobExecutorEmulator = new JobExecutorEmulator(environmentFactory, jobs.get(0));
- jobExecutorEmulator.synchroniseAfterJobExecution(Thread.currentThread().getName());
+ //SynchronizableCommandExecutor jobExecutorEmulator = new SynchronizableCommandExecutor(environmentFactory, jobs.get(0));
+ SynchronizableCommandExecutor jobExecutorEmulator = new SynchronizableCommandExecutor(environmentFactory, jobs.get(0));
+ jobExecutorEmulator.synchroniseAfterExecution();
jobExecutorEmulator.start();
- jobExecutorEmulator.waitUntilJobExecuted(true); // transaction will be stalled
+ jobExecutorEmulator.waitUntilExecutionFinished(true); // transaction will be stalled until signal is done
// Cause conflicting transaction
final Execution executionAtState = processInstance.findActiveExecutionIn("wait");
assertNotNull(executionAtState);
- OffloadThread signalThread = new OffloadThread(new ThreadCallback() {
- public void executeInThread() {
- executionService.signalExecutionById(executionAtState.getId(), "go on");
- }
- });
+
+ SignalCmd signalCmd = new SignalCmd(executionAtState.getId(), "go on", null);
+ SynchronizableCommandExecutor signalThread = new SynchronizableCommandExecutor(environmentFactory, signalCmd);
signalThread.start();
- /*
- // Checking current stacktrace of thread
- int i = 1;
- while (i == 1) {
- System.out.println("-----------> STATE = " + temp.getState());
- StackTraceElement[] stack = temp.getStackTrace();
- for (StackTraceElement e : stack) {
- System.out.println("-----------> " + e);
- }
-
- synchronized (this) {
- try {
- wait(1000L);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- */
-
// Best effort: wait 1 sec and see if the staleObjectException has been caused
synchronized (this) {
wait(1000L);
}
jobExecutorEmulator.goOn();
+
jobExecutorEmulator.join();
+ signalThread.join();
- if (jobExecutorEmulator.getException() != null) {
- fail("Error while executing job: " + jobExecutorEmulator.getException().getMessage());
- } if (signalThread.getException() != null) {
- fail("Error while executing signal " + signalThread.getException().getMessage());
+ if (!(jobExecutorEmulator.getException() instanceof StaleStateException
+ || signalThread.getException() instanceof StaleStateException)) {
+ fail("None of the threads threw a StaleStateException");
}
}
Modified: jbpm4/trunk/modules/test-concurrent/src/test/resources/jbpm.cfg.xml
===================================================================
--- jbpm4/trunk/modules/test-concurrent/src/test/resources/jbpm.cfg.xml 2009-06-19 15:53:46 UTC (rev 5068)
+++ jbpm4/trunk/modules/test-concurrent/src/test/resources/jbpm.cfg.xml 2009-06-19 17:26:38 UTC (rev 5069)
@@ -4,8 +4,24 @@
<import resource="jbpm.default.cfg.xml" />
<import resource="jbpm.jpdl.cfg.xml" />
+
+ <!-- we need to remove the retry interceptor, so we cant use the default
<import resource="jbpm.tx.hibernate.cfg.xml" />
+ -->
+
+ <process-engine-context>
+ <command-service>
+ <environment-interceptor />
+ <standard-transaction-interceptor />
+ </command-service>
+ </process-engine-context>
+ <transaction-context>
+ <transaction />
+ <hibernate-session />
+ </transaction-context>
+
+
<!--
In the concurrency tests, we'll emulate the job executor to have full
control on when syncing occurs
More information about the jbpm-commits
mailing list