Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2019-02-01 11:04:51 -0500
committerEike Stepper2019-02-01 11:04:51 -0500
commitddbf0ebab3920ef12645400a1b929d8accd97831 (patch)
tree5e384f10a49d84d3a0e50c927d444481c87616ee /plugins/org.eclipse.emf.cdo.tests/src
parent3ff7e9362774a011ceb8e5937ab4f20e87fe27b0 (diff)
downloadcdo-ddbf0ebab3920ef12645400a1b929d8accd97831.tar.gz
cdo-ddbf0ebab3920ef12645400a1b929d8accd97831.tar.xz
cdo-ddbf0ebab3920ef12645400a1b929d8accd97831.zip
[544045] Various concurrency improvements (IWorkSerializer, ThreadPool, RWOLockManager)
https://bugs.eclipse.org/bugs/show_bug.cgi?id=544045
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.tests/src')
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java172
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417825_Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417844_Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Config.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java5
6 files changed, 191 insertions, 5 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java
index 4a191615d1..4dd978c44c 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java
@@ -22,6 +22,8 @@ import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.tests.model1.Customer;
+import org.eclipse.emf.cdo.tests.model1.Model1Factory;
import org.eclipse.emf.cdo.tests.util.TestAdapter;
import org.eclipse.emf.cdo.transaction.CDOCommitContext;
import org.eclipse.emf.cdo.transaction.CDOPushTransaction;
@@ -30,8 +32,10 @@ import org.eclipse.emf.cdo.transaction.CDOTransactionConflictEvent;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler2;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
+import org.eclipse.emf.cdo.util.ConcurrentAccessException;
import org.eclipse.emf.cdo.view.CDOView;
+import org.eclipse.net4j.signal.SignalCounter;
import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
@@ -45,8 +49,10 @@ import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* See bug 213782, bug 201366
@@ -230,6 +236,156 @@ public class TransactionTest extends AbstractCDOTest
}
}
+ public void testCommitManyTransactionsMultiThread() throws Exception
+ {
+ final int RUNS = 1;
+ final int THREADS = 1000;
+ final int TIMEOUT = 10; // Minutes.
+ final boolean pessimistic = true;
+
+ CDOSession session = openSession();
+
+ CDOTransaction initialTransaction = session.openTransaction();
+ CDOResource resource = initialTransaction.createResource(getResourcePath("myResource"));
+
+ final Company initialCompany = getModel1Factory().createCompany();
+ resource.getContents().add(initialCompany);
+ initialTransaction.commit();
+
+ SignalCounter signalCounter = new SignalCounter(((CDONet4jSession)session).options().getNet4jProtocol());
+
+ for (int run = 1; run <= RUNS; run++)
+ {
+ System.out.println("RUN " + run);
+
+ AtomicInteger concurrentAccessExceptions = new AtomicInteger();
+ CountDownLatch latch = new CountDownLatch(THREADS);
+ List<Thread> threadList = new ArrayList<Thread>();
+
+ for (int thread = 0; thread < THREADS; thread++)
+ {
+ final CDOTransaction transaction = session.openTransaction();
+ // transaction.options().setCommitInfoTimeout(1000000);
+
+ final Company company = transaction.getObject(initialCompany);
+ final Customer newCustomer = Model1Factory.eINSTANCE.createCustomer();
+
+ threadList.add(new Committer(transaction, concurrentAccessExceptions, latch, new Callable<Boolean>()
+ {
+ public Boolean call() throws Exception
+ {
+ if (pessimistic)
+ {
+ CDOUtil.getCDOObject(company).cdoWriteLock().lock(TIMEOUT, TimeUnit.MINUTES);
+ }
+
+ company.getCustomers().add(newCustomer);
+ return true;
+ }
+ }));
+ }
+
+ for (Thread thread : threadList)
+ {
+ thread.start();
+ }
+
+ if (!latch.await(TIMEOUT, TimeUnit.MINUTES))
+ {
+ fail("Timeout after " + TIMEOUT + " seconds");
+ }
+
+ System.out.println("ConcurrentAccessExceptions: " + concurrentAccessExceptions.get());
+ signalCounter.dump(IOUtil.OUT(), true);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class Committer extends Thread
+ {
+ private static final ThreadGroup THREAD_GROUP = new ThreadGroup("COMMITTERS");
+
+ private static final int ATTEMPTS = 200;
+
+ private final CDOTransaction transaction;
+
+ private final AtomicInteger concurrentAccessExceptions;
+
+ private final CountDownLatch latch;
+
+ private final Callable<Boolean> operation;
+
+ private Callable<Boolean> callable = new Callable<Boolean>()
+ {
+ private int attempt;
+
+ public Boolean call() throws Exception
+ {
+ ++attempt;
+ operation.call();
+
+ try
+ {
+ transaction.commit();
+ }
+ catch (ConcurrentAccessException ex)
+ {
+ concurrentAccessExceptions.incrementAndGet();
+
+ if (attempt < ATTEMPTS)
+ {
+ transaction.rollback();
+ return true;
+ }
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
+
+ return false;
+ }
+ };
+
+ public Committer(CDOTransaction transaction, AtomicInteger concurrentAccessExceptions, CountDownLatch latch, Callable<Boolean> operation)
+ {
+ super(THREAD_GROUP, "Committer-" + transaction.getViewID());
+ this.transaction = transaction;
+ this.concurrentAccessExceptions = concurrentAccessExceptions;
+ this.latch = latch;
+ this.operation = operation;
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ while (transaction.syncExec(callable))
+ {
+ // Do nothing.
+ }
+ }
+ catch (Exception ex)
+ {
+ System.out.println(ex.getClass().getName() + " --> " + ex.getMessage());
+ }
+ finally
+ {
+ try
+ {
+ transaction.close();
+ }
+ finally
+ {
+ latch.countDown();
+ }
+ }
+ }
+ }
+
public void testPushModeNewObjects() throws Exception
{
IOUtil.OUT().println("Creating category1");
@@ -641,4 +797,20 @@ public class TransactionTest extends AbstractCDOTest
company.setName("ABC");
transaction.commit();
}
+ //
+ // public static <V> V syncCommit(CDOTransaction transaction, int commitAttempts, EObject object, Transactional<V>
+ // transactional)
+ // throws ConcurrentAccessException, CommitException
+ // {
+ // int xxx;
+ // return null;
+ // }
+ //
+ // /**
+ // * @author Eike Stepper
+ // */
+ // public interface Transactional<S>
+ // {
+ //
+ // }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417825_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417825_Test.java
index cefd1a5581..6032bbb131 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417825_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417825_Test.java
@@ -16,6 +16,7 @@ import org.eclipse.emf.internal.cdo.session.CDOSessionImpl;
import org.eclipse.emf.internal.cdo.session.SessionUtil;
import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
/**
* Bug 417825 - Invalidator can die if CDOSession can not be activated within 100ms.
@@ -39,7 +40,7 @@ public class Bugzilla_417825_Test extends AbstractCDOTest
{
CDOSessionImpl session2 = (CDOSessionImpl)openSession();
assertEquals(true, session2.isActive());
- assertEquals(true, session2.getInvalidator().isActive());
+ assertEquals(true, LifecycleUtil.isActive(session2.getInvalidator()));
}
finally
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417844_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417844_Test.java
index 14b34b6291..c3f375ca51 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417844_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417844_Test.java
@@ -19,6 +19,7 @@ import org.eclipse.emf.internal.cdo.view.CDOViewImpl;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
/**
* Bug 417844 - InvalidationRunner can die if invalidations come too early.
@@ -53,7 +54,7 @@ public class Bugzilla_417844_Test extends AbstractCDOTest
{
CDOViewImpl view = (CDOViewImpl)session.openView();
assertEquals(true, view.isActive());
- assertEquals(true, view.getInvalidationRunner().isActive());
+ assertEquals(true, LifecycleUtil.isActive(view.getInvalidator()));
}
finally
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Config.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Config.java
index 0c66fd3ddd..aff2dad2a4 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Config.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Config.java
@@ -26,7 +26,9 @@ public abstract class Config implements IConfig
{
private static final long serialVersionUID = 1L;
- protected static ExecutorService executorService = ThreadPool.create("test", 10, 1000, 10);
+ protected static final int MAX_THREADS_PER_POOL = 10000;
+
+ protected static ExecutorService executorService = ThreadPool.create("test", 10, MAX_THREADS_PER_POOL, 10);
private String name;
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
index 4d4c3460f8..3d76e460d6 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
@@ -74,6 +74,7 @@ import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
import org.eclipse.net4j.util.concurrent.DelegatingExecutorService;
import org.eclipse.net4j.util.concurrent.ExecutorServiceFactory;
+import org.eclipse.net4j.util.concurrent.ThreadPool;
import org.eclipse.net4j.util.container.ContainerUtil;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
@@ -134,12 +135,16 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
private static final boolean LOG_MULTI_VIEW_COMMIT = false;
- private static final Boolean enableServerBrowser = Boolean.getBoolean("org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig.enableServerBrowser");
+ private static final boolean enableServerBrowser = Boolean.getBoolean("org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig.enableServerBrowser");
+
+ private static final boolean useGlobalThreadPool = Boolean.getBoolean("org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig.useGlobalThreadPool");
private static final long serialVersionUID = 1L;
protected static IManagedContainer serverContainer;
+ protected static ExecutorService serverThreadPool = useGlobalThreadPool ? executorService : ThreadPool.create("server", 10, MAX_THREADS_PER_POOL, 10);
+
protected static Map<String, InternalRepository> repositories;
private static String lastRepoProps;
@@ -348,7 +353,7 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
@Override
public ExecutorService create(String threadGroupName)
{
- return new DelegatingExecutorService(executorService);
+ return new DelegatingExecutorService(serverThreadPool);
}
});
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java
index 6bf0e27140..b7cd258b4e 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java
@@ -624,6 +624,11 @@ public abstract class SessionConfig extends Config implements ISessionConfig
public void setUp() throws Exception
{
super.setUp();
+ if (!usesServerContainer())
+ {
+ JVMUtil.prepareContainer(getServerContainer());
+ }
+
JVMUtil.prepareContainer(getClientContainer());
}

Back to the top