Search in sources :

Example 21 with BinaryLatch

use of org.neo4j.util.concurrent.BinaryLatch in project neo4j by neo4j.

the class IndexingServiceTest method constraintIndexesWithoutConstraintsMustGetPopulatingProxies.

@Test
void constraintIndexesWithoutConstraintsMustGetPopulatingProxies() throws Exception {
    // given
    AtomicReference<BinaryLatch> populationStartLatch = latchedIndexPopulation();
    try {
        long indexId = 1;
        // Note the lack of an "owned constraint id".
        IndexDescriptor index = uniqueIndex.materialise(indexId);
        IndexingService indexing = newIndexingServiceWithMockedDependencies(populator, accessor, withData(), index);
        when(indexProvider.getInitialState(eq(index), any())).thenReturn(POPULATING);
        // when
        life.start();
        // then
        assertEquals(POPULATING, indexing.getIndexProxy(index).getState());
    } finally {
        populationStartLatch.get().release();
    }
}
Also used : IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) BinaryLatch(org.neo4j.util.concurrent.BinaryLatch) Test(org.junit.jupiter.api.Test)

Example 22 with BinaryLatch

use of org.neo4j.util.concurrent.BinaryLatch in project neo4j by neo4j.

the class IndexingServiceTest method shouldNotLoseIndexDescriptorDueToOtherVerySimilarIndexDuringRecovery.

@Test
void shouldNotLoseIndexDescriptorDueToOtherVerySimilarIndexDuringRecovery() throws Exception {
    // GIVEN
    AtomicReference<BinaryLatch> populationStartLatch = latchedIndexPopulation();
    long nodeId = 0;
    Update update = addNodeUpdate(nodeId, "value");
    when(indexStatisticsStore.indexSample(anyLong())).thenReturn(new IndexSample(100, 42, 42));
    // For some reason the usual accessor returned null from newUpdater, even when told to return the updater
    // so spying on a real object instead.
    IndexAccessor accessor = spy(new TrackingIndexAccessor());
    IndexingService indexing = newIndexingServiceWithMockedDependencies(populator, accessor, withData(update), index);
    when(indexProvider.getInitialState(index, NULL)).thenReturn(ONLINE);
    life.init();
    populationStartLatch.getAndSet(new BinaryLatch()).release();
    // WHEN dropping another index, which happens to be identical to the existing one except for different index config... while recovering
    IndexConfig indexConfig = index.getIndexConfig().withIfAbsent("a", Values.booleanValue(true));
    IndexDescriptor otherIndex = index.withIndexConfig(indexConfig);
    indexing.createIndexes(AUTH_DISABLED, otherIndex);
    indexing.dropIndex(otherIndex);
    // and WHEN finally creating our index again (at a later point in recovery)
    indexing.createIndexes(AUTH_DISABLED, index);
    reset(accessor);
    indexing.applyUpdates(nodeIdsAsIndexUpdates(nodeId), NULL);
    // and WHEN starting, i.e. completing recovery
    life.start();
    IndexProxy indexProxy = indexing.getIndexProxy(index);
    try {
        assertNull(indexProxy.getDescriptor().getIndexConfig().get("a"));
        // The existing online index got nuked during recovery.
        assertThat(indexProxy.getState()).isEqualTo(POPULATING);
    } finally {
        populationStartLatch.get().release();
    }
}
Also used : IndexSample(org.neo4j.kernel.api.index.IndexSample) IndexConfig(org.neo4j.internal.schema.IndexConfig) IndexAccessor(org.neo4j.kernel.api.index.IndexAccessor) IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) BinaryLatch(org.neo4j.util.concurrent.BinaryLatch) Test(org.junit.jupiter.api.Test)

Example 23 with BinaryLatch

use of org.neo4j.util.concurrent.BinaryLatch in project neo4j by neo4j.

the class IndexingServiceTest method latchedIndexPopulation.

private AtomicReference<BinaryLatch> latchedIndexPopulation() {
    AtomicReference<BinaryLatch> populationStartLatch = new AtomicReference<>(new BinaryLatch());
    scheduler.setThreadFactory(Group.INDEX_POPULATION, (group, parent) -> new GroupedDaemonThreadFactory(group, parent) {

        @Override
        public Thread newThread(Runnable job) {
            return super.newThread(() -> {
                populationStartLatch.get().await();
                job.run();
            });
        }
    });
    return populationStartLatch;
}
Also used : GroupedDaemonThreadFactory(org.neo4j.kernel.impl.scheduler.GroupedDaemonThreadFactory) AtomicReference(java.util.concurrent.atomic.AtomicReference) BinaryLatch(org.neo4j.util.concurrent.BinaryLatch)

Example 24 with BinaryLatch

use of org.neo4j.util.concurrent.BinaryLatch in project neo4j by neo4j.

the class DatabaseIndexAccessorTest method shouldStopSamplingWhenIndexIsDropped.

@Test
public void shouldStopSamplingWhenIndexIsDropped() throws Exception {
    // given
    updateAndCommit(asList(add(nodeId, value), add(nodeId2, value2)));
    // when
    var indexReader = accessor.newValueReader();
    BinaryLatch dropLatch = new BinaryLatch();
    BinaryLatch sampleLatch = new BinaryLatch();
    LuceneIndexSampler indexSampler = spy((LuceneIndexSampler) indexReader.createSampler());
    doAnswer(inv -> {
        var obj = inv.callRealMethod();
        // We have now started the sampling, let the index try to drop
        dropLatch.release();
        // Wait for the drop to be blocked
        sampleLatch.await();
        return obj;
    }).when(indexSampler).newTask();
    List<Future<?>> futures = new ArrayList<>();
    try (var reader = indexReader;
        /* do not inline! */
        IndexSampler sampler = indexSampler) /* do not inline! */
    {
        futures.add(threading.execute((IOFunction<Void, Void>) nothing -> {
            try {
                indexSampler.sampleIndex(NULL);
                fail("expected exception");
            } catch (IndexNotFoundKernelException e) {
                assertEquals("Index dropped while sampling.", e.getMessage());
            } finally {
                dropLatch.release();
            }
            return nothing;
        }, null));
        futures.add(threading.executeAndAwait((IOFunction<Void, Void>) nothing -> {
            dropLatch.await();
            accessor.drop();
            return nothing;
        }, null, waitingWhileIn(TaskCoordinator.class, "awaitCompletion"), 10, MINUTES));
    } finally {
        // drop is blocked, okay to finish sampling (will fail since index is dropped)
        sampleLatch.release();
        for (Future<?> future : futures) {
            future.get();
        }
    }
}
Also used : IOFunction(org.neo4j.function.IOFunction) ArrayList(java.util.ArrayList) Future(java.util.concurrent.Future) IndexNotFoundKernelException(org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException) BinaryLatch(org.neo4j.util.concurrent.BinaryLatch) IndexSampler(org.neo4j.kernel.api.index.IndexSampler) Test(org.junit.Test)

Example 25 with BinaryLatch

use of org.neo4j.util.concurrent.BinaryLatch in project neo4j by neo4j.

the class TinyLockManager method lock.

public void lock(int recordId) {
    Integer record = recordId;
    BinaryLatch myLatch = new BinaryLatch();
    for (; ; ) {
        BinaryLatch existingLatch = map.putIfAbsent(record, myLatch);
        if (existingLatch == null) {
            break;
        } else {
            existingLatch.await();
        }
    }
}
Also used : BinaryLatch(org.neo4j.util.concurrent.BinaryLatch)

Aggregations

BinaryLatch (org.neo4j.util.concurrent.BinaryLatch)31 Test (org.junit.jupiter.api.Test)21 RepeatedTest (org.junit.jupiter.api.RepeatedTest)5 Transaction (org.neo4j.graphdb.Transaction)5 ExecutorService (java.util.concurrent.ExecutorService)4 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)4 Node (org.neo4j.graphdb.Node)4 KernelTransaction (org.neo4j.kernel.api.KernelTransaction)4 AtomicLong (java.util.concurrent.atomic.AtomicLong)3 Timeout (org.junit.jupiter.api.Timeout)3 ValueSource (org.junit.jupiter.params.provider.ValueSource)3 InternalTransaction (org.neo4j.kernel.impl.coreapi.InternalTransaction)3 Flushable (java.io.Flushable)2 Path (java.nio.file.Path)2 ArrayList (java.util.ArrayList)2 Future (java.util.concurrent.Future)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 RelationshipType (org.neo4j.graphdb.RelationshipType)2