Search in sources :

Example 1 with OtherThreadExecutor

use of org.neo4j.test.OtherThreadExecutor in project neo4j by neo4j.

the class NestedTransactionLocksIT method nestedTransactionCanAcquireLocksFromTransactionObject.

@Test
public void nestedTransactionCanAcquireLocksFromTransactionObject() throws Exception {
    // given
    Node resource = createNode();
    try (Transaction outerTx = db.beginTx();
        Transaction nestedTx = db.beginTx()) {
        assertNotSame(outerTx, nestedTx);
        try (OtherThreadExecutor<Void> otherThread = new OtherThreadExecutor<>("other thread", null)) {
            // when
            Lock lock = nestedTx.acquireWriteLock(resource);
            Future<Lock> future = tryToAcquireSameLockOnAnotherThread(resource, otherThread);
            // then
            acquireOnOtherThreadTimesOut(future);
            // and when
            lock.release();
            //then
            assertNotNull(future.get());
        }
    }
}
Also used : Transaction(org.neo4j.graphdb.Transaction) OtherThreadExecutor(org.neo4j.test.OtherThreadExecutor) Node(org.neo4j.graphdb.Node) Lock(org.neo4j.graphdb.Lock) Test(org.junit.Test)

Example 2 with OtherThreadExecutor

use of org.neo4j.test.OtherThreadExecutor in project neo4j by neo4j.

the class ManyPropertyKeysIT method concurrently_creating_same_property_key_in_different_transactions_should_end_up_with_same_key_id.

@Test
public void concurrently_creating_same_property_key_in_different_transactions_should_end_up_with_same_key_id() throws Exception {
    // GIVEN
    GraphDatabaseAPI db = (GraphDatabaseAPI) new TestGraphDatabaseFactory().newImpermanentDatabase();
    OtherThreadExecutor<WorkerState> worker1 = new OtherThreadExecutor<>("w1", new WorkerState(db));
    OtherThreadExecutor<WorkerState> worker2 = new OtherThreadExecutor<>("w2", new WorkerState(db));
    worker1.execute(new BeginTx());
    worker2.execute(new BeginTx());
    // WHEN
    String key = "mykey";
    worker1.execute(new CreateNodeAndSetProperty(key));
    worker2.execute(new CreateNodeAndSetProperty(key));
    worker1.execute(new FinishTx());
    worker2.execute(new FinishTx());
    worker1.close();
    worker2.close();
    // THEN
    assertEquals(1, propertyKeyCount(db));
    db.shutdown();
}
Also used : GraphDatabaseAPI(org.neo4j.kernel.internal.GraphDatabaseAPI) OtherThreadExecutor(org.neo4j.test.OtherThreadExecutor) TestGraphDatabaseFactory(org.neo4j.test.TestGraphDatabaseFactory) Test(org.junit.Test)

Example 3 with OtherThreadExecutor

use of org.neo4j.test.OtherThreadExecutor in project neo4j by neo4j.

the class TransactionConstraintsIT method deadlockDetectionBetween.

private void deadlockDetectionBetween(HighlyAvailableGraphDatabase slave1, final HighlyAvailableGraphDatabase slave2) throws Exception {
    // GIVEN
    // -- two members acquiring a read lock on the same entity
    final Node commonNode;
    try (Transaction tx = slave1.beginTx()) {
        commonNode = slave1.createNode();
        tx.success();
    }
    OtherThreadExecutor<HighlyAvailableGraphDatabase> thread2 = new OtherThreadExecutor<>("T2", slave2);
    Transaction tx1 = slave1.beginTx();
    Transaction tx2 = thread2.execute(new BeginTx());
    tx1.acquireReadLock(commonNode);
    thread2.execute(state -> tx2.acquireReadLock(commonNode));
    // -- and one of them wanting (and awaiting) to upgrade its read lock to a write lock
    Future<Lock> writeLockFuture = thread2.executeDontWait(state -> {
        try (Transaction ignored = tx2) {
            return tx2.acquireWriteLock(commonNode);
        }
    });
    for (int i = 0; i < 10; i++) {
        thread2.waitUntilThreadState(Thread.State.TIMED_WAITING, Thread.State.WAITING);
        Thread.sleep(2);
    }
    try (// Close transaction no matter what happens
    Transaction ignored = tx1) {
        // WHEN
        tx1.acquireWriteLock(commonNode);
        // -- Deadlock detection is non-deterministic, so either the slave or the master will detect it
        writeLockFuture.get();
        fail("Deadlock exception should have been thrown");
    } catch (DeadlockDetectedException e) {
    // THEN -- deadlock should be avoided with this exception
    } catch (ExecutionException e) {
        // OR -- the tx2 thread fails with executionexception, caused by deadlock on its end
        assertThat(e.getCause(), instanceOf(DeadlockDetectedException.class));
    }
    thread2.close();
}
Also used : Transaction(org.neo4j.graphdb.Transaction) OtherThreadExecutor(org.neo4j.test.OtherThreadExecutor) HighlyAvailableGraphDatabase(org.neo4j.kernel.ha.HighlyAvailableGraphDatabase) Node(org.neo4j.graphdb.Node) DeadlockDetectedException(org.neo4j.kernel.DeadlockDetectedException) ExecutionException(java.util.concurrent.ExecutionException) Lock(org.neo4j.graphdb.Lock)

Example 4 with OtherThreadExecutor

use of org.neo4j.test.OtherThreadExecutor in project neo4j by neo4j.

the class IndexOperationsIT method put_if_absent_works_across_instances.

@Test
public void put_if_absent_works_across_instances() throws Exception {
    // GIVEN
    // -- two instances, each begin a transaction
    String key = "key2", value = "value2";
    HighlyAvailableGraphDatabase db1 = cluster.getMaster(), db2 = cluster.getAnySlave();
    long node = createNode(db1, key, value, false);
    cluster.sync();
    OtherThreadExecutor<HighlyAvailableGraphDatabase> w1 = new OtherThreadExecutor<>("w1", db1);
    OtherThreadExecutor<HighlyAvailableGraphDatabase> w2 = new OtherThreadExecutor<>("w2", db2);
    Transaction tx1 = w1.execute(new BeginTx());
    Transaction tx2 = w2.execute(new BeginTx());
    // WHEN
    // -- second instance does putIfAbsent --> null
    assertNull(w2.execute(new PutIfAbsent(node, key, value)));
    // -- get a future to first instance putIfAbsent. Wait for it to go and await the lock
    Future<Node> w1Future = w1.executeDontWait(new PutIfAbsent(node, key, value));
    w1.waitUntilWaiting();
    // -- second instance completes tx
    w2.execute(new FinishTx(tx2, true));
    tx2.success();
    tx2.close();
    // THEN
    // -- first instance can complete the future with a non-null result
    assertNotNull(w1Future.get());
    w1.execute(new FinishTx(tx1, true));
    // -- assert the index has got one entry and both instances have the same data
    assertNodeAndIndexingExists(db1, node, key, value);
    assertNodeAndIndexingExists(db2, node, key, value);
    cluster.sync();
    assertNodeAndIndexingExists(cluster.getAnySlave(db1, db2), node, key, value);
    w2.close();
    w1.close();
}
Also used : OtherThreadExecutor(org.neo4j.test.OtherThreadExecutor) Transaction(org.neo4j.graphdb.Transaction) FinishTx(org.neo4j.ha.FinishTx) HighlyAvailableGraphDatabase(org.neo4j.kernel.ha.HighlyAvailableGraphDatabase) Node(org.neo4j.graphdb.Node) BeginTx(org.neo4j.ha.BeginTx) Test(org.junit.Test)

Example 5 with OtherThreadExecutor

use of org.neo4j.test.OtherThreadExecutor in project neo4j by neo4j.

the class DynamicTaskExecutorTest method shouldLetShutdownCompleteInEventOfPanic.

@Test
public void shouldLetShutdownCompleteInEventOfPanic() throws Exception {
    // GIVEN
    final TaskExecutor<Void> executor = new DynamicTaskExecutor<>(2, 0, 10, PARK, getClass().getSimpleName());
    IOException exception = new IOException("Failure");
    // WHEN
    FailingTask failingTask = new FailingTask(exception);
    executor.submit(failingTask);
    failingTask.latch.await();
    // WHEN
    try (OtherThreadExecutor<Void> closer = new OtherThreadExecutor<>("closer", null)) {
        Future<Void> shutdown = closer.executeDontWait(new WorkerCommand<Void, Void>() {

            @Override
            public Void doWork(Void state) throws Exception {
                executor.close();
                return null;
            }
        });
        while (!closer.waitUntilWaiting().isAt(DynamicTaskExecutor.class, "close")) {
            Thread.sleep(10);
        }
        // Here we've got a shutdown call stuck awaiting queue to be empty (since true was passed in)
        // at the same time we've got a FailingTask ready to throw its exception and another task
        // sitting in the queue after it. Now make the task throw that exception.
        failingTask.latch.release();
        // Some time after throwing this, the shutdown request should have been completed.
        shutdown.get();
    }
}
Also used : OtherThreadExecutor(org.neo4j.test.OtherThreadExecutor) IOException(java.io.IOException) IOException(java.io.IOException) Test(org.junit.Test)

Aggregations

OtherThreadExecutor (org.neo4j.test.OtherThreadExecutor)5 Test (org.junit.Test)4 Node (org.neo4j.graphdb.Node)3 Transaction (org.neo4j.graphdb.Transaction)3 Lock (org.neo4j.graphdb.Lock)2 HighlyAvailableGraphDatabase (org.neo4j.kernel.ha.HighlyAvailableGraphDatabase)2 IOException (java.io.IOException)1 ExecutionException (java.util.concurrent.ExecutionException)1 BeginTx (org.neo4j.ha.BeginTx)1 FinishTx (org.neo4j.ha.FinishTx)1 DeadlockDetectedException (org.neo4j.kernel.DeadlockDetectedException)1 GraphDatabaseAPI (org.neo4j.kernel.internal.GraphDatabaseAPI)1 TestGraphDatabaseFactory (org.neo4j.test.TestGraphDatabaseFactory)1