Search in sources :

Example 6 with Condition

use of org.apache.cassandra.utils.concurrent.Condition in project cassandra by apache.

the class PreviewRepairTest method testFinishingNonIntersectingIncRepairDuringPreview.

/**
 * Same as testFinishingIncRepairDuringPreview but the previewed range does not intersect the incremental repair
 * so both preview and incremental repair should finish fine (without any mismatches)
 */
@Test
public void testFinishingNonIntersectingIncRepairDuringPreview() throws IOException, InterruptedException, ExecutionException {
    ExecutorService es = Executors.newSingleThreadExecutor();
    try (Cluster cluster = init(Cluster.build(2).withConfig(config -> config.with(GOSSIP).with(NETWORK)).start())) {
        cluster.schemaChange("create table " + KEYSPACE + ".tbl (id int primary key, t int)");
        insert(cluster.coordinator(1), 0, 100);
        cluster.forEach((node) -> node.flush(KEYSPACE));
        assertTrue(cluster.get(1).callOnInstance(repair(options(false, false))).success);
        insert(cluster.coordinator(1), 100, 100);
        cluster.forEach((node) -> node.flush(KEYSPACE));
        // pause preview repair validation messages on node2 until node1 has finished
        Condition previewRepairStarted = newOneTimeCondition();
        Condition continuePreviewRepair = newOneTimeCondition();
        DelayFirstRepairTypeMessageFilter filter = validationRequest(previewRepairStarted, continuePreviewRepair);
        cluster.filters().outbound().verbs(VALIDATION_REQ.id).from(1).to(2).messagesMatching(filter).drop();
        // get local ranges to repair two separate ranges:
        List<String> localRanges = cluster.get(1).callOnInstance(() -> {
            List<String> res = new ArrayList<>();
            for (Range<Token> r : instance.getLocalReplicas(KEYSPACE).ranges()) res.add(r.left.getTokenValue() + ":" + r.right.getTokenValue());
            return res;
        });
        assertEquals(2, localRanges.size());
        Future<RepairResult> repairStatusFuture = es.submit(() -> cluster.get(1).callOnInstance(repair(options(true, false, localRanges.get(0)))));
        // wait for node1 to start validation compaction
        previewRepairStarted.await();
        // this needs to finish before the preview repair is unpaused on node2
        assertTrue(cluster.get(1).callOnInstance(repair(options(false, false, localRanges.get(1)))).success);
        continuePreviewRepair.signalAll();
        RepairResult rs = repairStatusFuture.get();
        // repair should succeed
        assertTrue(rs.success);
        // and no mismatches
        assertFalse(rs.wasInconsistent);
    } finally {
        es.shutdown();
    }
}
Also used : Condition.newOneTimeCondition(org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition) Condition(org.apache.cassandra.utils.concurrent.Condition) ExecutorService(java.util.concurrent.ExecutorService) ArrayList(java.util.ArrayList) Cluster(org.apache.cassandra.distributed.Cluster) Token(org.apache.cassandra.dht.Token) RepairResult(org.apache.cassandra.distributed.shared.RepairResult) Test(org.junit.Test)

Example 7 with Condition

use of org.apache.cassandra.utils.concurrent.Condition in project cassandra by apache.

the class ReadRepairTest method readRepairRTRangeMovementTest.

@Test
public void readRepairRTRangeMovementTest() throws Throwable {
    ExecutorService es = Executors.newFixedThreadPool(1);
    String key = "test1";
    try (Cluster cluster = init(Cluster.build().withConfig(config -> config.with(Feature.GOSSIP, Feature.NETWORK).set("read_request_timeout", String.format("%dms", Integer.MAX_VALUE))).withTokenSupplier(TokenSupplier.evenlyDistributedTokens(4)).withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(4, "dc0", "rack0")).withNodes(3).start())) {
        cluster.schemaChange("CREATE TABLE distributed_test_keyspace.tbl (\n" + "    key text,\n" + "    column1 int,\n" + "    PRIMARY KEY (key, column1)\n" + ") WITH CLUSTERING ORDER BY (column1 ASC)");
        cluster.forEach(i -> i.runOnInstance(() -> open(KEYSPACE).getColumnFamilyStore("tbl").disableAutoCompaction()));
        for (int i = 1; i <= 2; i++) {
            cluster.get(i).executeInternal("DELETE FROM distributed_test_keyspace.tbl USING TIMESTAMP 50 WHERE key=?;", key);
            cluster.get(i).executeInternal("DELETE FROM distributed_test_keyspace.tbl USING TIMESTAMP 80 WHERE key=? and column1 >= ? and column1 < ?;", key, 10, 100);
            cluster.get(i).executeInternal("DELETE FROM distributed_test_keyspace.tbl USING TIMESTAMP 70 WHERE key=? and column1 = ?;", key, 30);
            cluster.get(i).flush(KEYSPACE);
        }
        cluster.get(3).executeInternal("DELETE FROM distributed_test_keyspace.tbl USING TIMESTAMP 100 WHERE key=?;", key);
        cluster.get(3).flush(KEYSPACE);
        // pause the read until we have bootstrapped a new node below
        Condition continueRead = newOneTimeCondition();
        Condition readStarted = newOneTimeCondition();
        cluster.filters().outbound().from(3).to(1, 2).verbs(READ_REQ.id).messagesMatching((i, i1, iMessage) -> {
            try {
                readStarted.signalAll();
                continueRead.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return false;
        }).drop();
        Future<Object[][]> read = es.submit(() -> cluster.coordinator(3).execute("SELECT * FROM distributed_test_keyspace.tbl WHERE key=? and column1 >= ? and column1 <= ?", ALL, key, 20, 40));
        readStarted.await();
        IInstanceConfig config = cluster.newInstanceConfig();
        config.set("auto_bootstrap", true);
        cluster.bootstrap(config).startup();
        continueRead.signalAll();
        read.get();
    } finally {
        es.shutdown();
    }
}
Also used : MethodDelegation(net.bytebuddy.implementation.MethodDelegation) ByteBuddy(net.bytebuddy.ByteBuddy) PendingRangeCalculatorService(org.apache.cassandra.service.PendingRangeCalculatorService) TokenSupplier(org.apache.cassandra.distributed.api.TokenSupplier) READ_REPAIR_REQ(org.apache.cassandra.net.Verb.READ_REPAIR_REQ) Future(java.util.concurrent.Future) DecoratedKey(org.apache.cassandra.db.DecoratedKey) READ_REQ(org.apache.cassandra.net.Verb.READ_REQ) Mutation(org.apache.cassandra.db.Mutation) Map(java.util.Map) Murmur3Partitioner(org.apache.cassandra.dht.Murmur3Partitioner) Assert.fail(org.junit.Assert.fail) IInstanceConfig(org.apache.cassandra.distributed.api.IInstanceConfig) ReplicaPlan(org.apache.cassandra.locator.ReplicaPlan) Condition.newOneTimeCondition(org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition) DatabaseDescriptor(org.apache.cassandra.config.DatabaseDescriptor) QUORUM(org.apache.cassandra.distributed.api.ConsistencyLevel.QUORUM) AssertUtils.row(org.apache.cassandra.distributed.shared.AssertUtils.row) ElementMatchers.named(net.bytebuddy.matcher.ElementMatchers.named) ConsistencyLevel(org.apache.cassandra.distributed.api.ConsistencyLevel) InetSocketAddress(java.net.InetSocketAddress) Executors(java.util.concurrent.Executors) ReadRepairStrategy(org.apache.cassandra.service.reads.repair.ReadRepairStrategy) AssertUtils.assertRows(org.apache.cassandra.distributed.shared.AssertUtils.assertRows) List(java.util.List) Keyspace.open(org.apache.cassandra.db.Keyspace.open) NetworkTopology(org.apache.cassandra.distributed.shared.NetworkTopology) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) PartitionUpdate(org.apache.cassandra.db.partitions.PartitionUpdate) READ_REPAIR_RSP(org.apache.cassandra.net.Verb.READ_REPAIR_RSP) Config(org.apache.cassandra.config.Config) Global.currentTimeMillis(org.apache.cassandra.utils.Clock.Global.currentTimeMillis) Callable(java.util.concurrent.Callable) Int32Type(org.apache.cassandra.db.marshal.Int32Type) Token(org.apache.cassandra.dht.Token) ICoordinator(org.apache.cassandra.distributed.api.ICoordinator) BlockingReadRepair(org.apache.cassandra.service.reads.repair.BlockingReadRepair) ALL(org.apache.cassandra.distributed.api.ConsistencyLevel.ALL) ExecutorService(java.util.concurrent.ExecutorService) Feature(org.apache.cassandra.distributed.api.Feature) StorageService(org.apache.cassandra.service.StorageService) Condition(org.apache.cassandra.utils.concurrent.Condition) Test(org.junit.Test) ClassLoadingStrategy(net.bytebuddy.dynamic.loading.ClassLoadingStrategy) Replica(org.apache.cassandra.locator.Replica) SuperCall(net.bytebuddy.implementation.bind.annotation.SuperCall) AssertUtils.assertEquals(org.apache.cassandra.distributed.shared.AssertUtils.assertEquals) Cluster(org.apache.cassandra.distributed.Cluster) Assert(org.junit.Assert) Condition.newOneTimeCondition(org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition) Condition(org.apache.cassandra.utils.concurrent.Condition) IInstanceConfig(org.apache.cassandra.distributed.api.IInstanceConfig) ExecutorService(java.util.concurrent.ExecutorService) Cluster(org.apache.cassandra.distributed.Cluster) Test(org.junit.Test)

Example 8 with Condition

use of org.apache.cassandra.utils.concurrent.Condition in project cassandra by apache.

the class RepairBoundaryTest method singleTokenRangeRepair.

@Test
public void singleTokenRangeRepair() {
    populate();
    verify();
    delete(cluster.get(1), 999, 1000);
    delete(cluster.get(3), 1001);
    cluster.get(2).runOnInstance(() -> {
        try {
            Map<String, String> options = new HashMap<>();
            options.put("ranges", "999:1000");
            options.put("incremental", "false");
            Condition await = newOneTimeCondition();
            instance.repair(KEYSPACE, options, of((tag, event) -> {
                if (event.getType() == COMPLETE)
                    await.signalAll();
            })).right.get();
            await.await(1L, MINUTES);
        } catch (Exception e) {
        }
    });
    assertRows(c2Row(999, 1001, 1999, 2000, 3001), cluster.get(2).executeInternal(ALL));
}
Also used : Condition(org.apache.cassandra.utils.concurrent.Condition) Condition.newOneTimeCondition(org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition) AfterClass(org.junit.AfterClass) BeforeClass(org.junit.BeforeClass) IOException(java.io.IOException) HashMap(java.util.HashMap) Condition(org.apache.cassandra.utils.concurrent.Condition) Test(org.junit.Test) MINUTES(java.util.concurrent.TimeUnit.MINUTES) ConsistencyLevel(org.apache.cassandra.distributed.api.ConsistencyLevel) LongToken.keyForToken(org.apache.cassandra.dht.Murmur3Partitioner.LongToken.keyForToken) ByteBuffer(java.nio.ByteBuffer) AssertUtils.assertRows(org.apache.cassandra.distributed.shared.AssertUtils.assertRows) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) COMPLETE(org.apache.cassandra.utils.progress.ProgressEventType.COMPLETE) Map(java.util.Map) Murmur3Partitioner(org.apache.cassandra.dht.Murmur3Partitioner) Cluster(org.apache.cassandra.distributed.Cluster) Condition.newOneTimeCondition(org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition) StorageService.instance(org.apache.cassandra.service.StorageService.instance) NETWORK(org.apache.cassandra.distributed.api.Feature.NETWORK) ImmutableList.of(com.google.common.collect.ImmutableList.of) GOSSIP(org.apache.cassandra.distributed.api.Feature.GOSSIP) HashMap(java.util.HashMap) IOException(java.io.IOException) Test(org.junit.Test)

Example 9 with Condition

use of org.apache.cassandra.utils.concurrent.Condition in project cassandra by apache.

the class ActiveRepairServiceTest method testQueueWhenPoolFullStrategy.

@Test
public void testQueueWhenPoolFullStrategy() throws InterruptedException {
    // Using RepairCommandPoolFullStrategy.queue, the pool is initialized to
    // repair_command_pool_size and any tasks which cannot immediately be
    // serviced are queued
    ExecutorService validationExecutor = ActiveRepairService.initializeExecutor(2, Config.RepairCommandPoolFullStrategy.queue);
    try {
        Condition allSubmitted = newOneTimeCondition();
        Condition blocked = newOneTimeCondition();
        CountDownLatch completed = new CountDownLatch(5);
        ExecutorService testExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            if (i < 4)
                testExecutor.submit(() -> validationExecutor.submit(new Task(blocked, completed)));
            else
                testExecutor.submit(() -> {
                    validationExecutor.submit(new Task(blocked, completed));
                    allSubmitted.signalAll();
                });
        }
        // Make sure all tasks have been submitted to the validation executor
        allSubmitted.await(TASK_SECONDS + 1, TimeUnit.SECONDS);
        // Give the tasks we expect to execute immediately chance to be scheduled
        Util.spinAssertEquals(2, ((ExecutorPlus) validationExecutor)::getActiveTaskCount, 1);
        Util.spinAssertEquals(3, ((ExecutorPlus) validationExecutor)::getPendingTaskCount, 1);
        // verify that we've reached a steady state with 2 threads actively processing and 3 queued tasks
        Assert.assertEquals(2, ((ExecutorPlus) validationExecutor).getActiveTaskCount());
        Assert.assertEquals(3, ((ExecutorPlus) validationExecutor).getPendingTaskCount());
        // allow executing tests to complete
        blocked.signalAll();
        completed.await(TASK_SECONDS + 1, TimeUnit.SECONDS);
    } finally {
        // necessary to unregister mbean
        validationExecutor.shutdownNow();
    }
}
Also used : Condition.newOneTimeCondition(org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition) Condition(org.apache.cassandra.utils.concurrent.Condition) ExecutorService(java.util.concurrent.ExecutorService) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 10 with Condition

use of org.apache.cassandra.utils.concurrent.Condition in project cassandra by apache.

the class ActiveRepairServiceTest method testRejectWhenPoolFullStrategy.

@Test
public void testRejectWhenPoolFullStrategy() throws InterruptedException {
    // Using RepairCommandPoolFullStrategy.reject, new threads are spawned up to
    // repair_command_pool_size, at which point futher submissions are rejected
    ExecutorService validationExecutor = ActiveRepairService.initializeExecutor(2, Config.RepairCommandPoolFullStrategy.reject);
    try {
        Condition blocked = newOneTimeCondition();
        CountDownLatch completed = new CountDownLatch(2);
        /*
             * CASSANDRA-16685 This is a Java bug. When the underlying executor's queue is a SynchronousQueue, there can
             * be races just after the ThreadPool's initialization while juggling and spinning up threads internally
             * leading to false rejections. That queue needs a thread ready to pick up the task immediately or it will
             * produce a reject exception upon 'offer()' method call on the executor's code. If the executor is still
             * initializing or threads are not ready to take work you can get false rejections.
             *
             * A sleep has been added to give time to the thread pool to be ready to get work.
             */
        Thread.sleep(250);
        validationExecutor.submit(new Task(blocked, completed));
        validationExecutor.submit(new Task(blocked, completed));
        try {
            validationExecutor.submit(new Task(blocked, completed));
            Assert.fail("Expected task submission to be rejected");
        } catch (RejectedExecutionException e) {
        // expected
        }
        // allow executing tests to complete
        blocked.signalAll();
        completed.await(TASK_SECONDS + 1, TimeUnit.SECONDS);
        // Submission is unblocked
        Thread.sleep(250);
        validationExecutor.submit(() -> {
        });
    } finally {
        // necessary to unregister mbean
        validationExecutor.shutdownNow();
    }
}
Also used : Condition.newOneTimeCondition(org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition) Condition(org.apache.cassandra.utils.concurrent.Condition) ExecutorService(java.util.concurrent.ExecutorService) CountDownLatch(java.util.concurrent.CountDownLatch) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) Test(org.junit.Test)

Aggregations

Condition (org.apache.cassandra.utils.concurrent.Condition)10 Condition.newOneTimeCondition (org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition)10 Test (org.junit.Test)9 ExecutorService (java.util.concurrent.ExecutorService)7 Cluster (org.apache.cassandra.distributed.Cluster)7 Token (org.apache.cassandra.dht.Token)3 RepairResult (org.apache.cassandra.distributed.shared.RepairResult)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 Executors (java.util.concurrent.Executors)2 Future (java.util.concurrent.Future)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 Murmur3Partitioner (org.apache.cassandra.dht.Murmur3Partitioner)2 ConsistencyLevel (org.apache.cassandra.distributed.api.ConsistencyLevel)2 ALL (org.apache.cassandra.distributed.api.ConsistencyLevel.ALL)2 GOSSIP (org.apache.cassandra.distributed.api.Feature.GOSSIP)2 AssertUtils.assertRows (org.apache.cassandra.distributed.shared.AssertUtils.assertRows)2 ImmutableList.of (com.google.common.collect.ImmutableList.of)1