Search in sources :

Example 1 with IdleStrategy

use of com.hazelcast.internal.util.concurrent.IdleStrategy in project hazelcast by hazelcast.

the class OperationExecutorImpl method initPartitionThreads.

private PartitionOperationThread[] initPartitionThreads(HazelcastProperties properties, String hzName, NodeExtension nodeExtension, ClassLoader configClassLoader) {
    int threadCount = properties.getInteger(PARTITION_OPERATION_THREAD_COUNT);
    if (threadAffinity.isEnabled()) {
        threadCount = threadAffinity.getThreadCount();
    }
    IdleStrategy idleStrategy = getIdleStrategy(properties, IDLE_STRATEGY);
    PartitionOperationThread[] threads = new PartitionOperationThread[threadCount];
    for (int threadId = 0; threadId < threads.length; threadId++) {
        String threadName = createThreadPoolName(hzName, "partition-operation") + threadId;
        // the normalQueue will be a blocking queue. We don't want to idle, because there are many operation threads.
        MPSCQueue<Object> normalQueue = new MPSCQueue<>(idleStrategy);
        OperationQueue operationQueue = new OperationQueueImpl(normalQueue, new ConcurrentLinkedQueue<>());
        PartitionOperationThread partitionThread = new PartitionOperationThread(threadName, threadId, operationQueue, logger, nodeExtension, partitionOperationRunners, configClassLoader);
        partitionThread.setThreadAffinity(threadAffinity);
        threads[threadId] = partitionThread;
        normalQueue.setConsumerThread(partitionThread);
    }
    // we need to assign the PartitionOperationThreads to all OperationRunners they own
    for (int partitionId = 0; partitionId < partitionOperationRunners.length; partitionId++) {
        int threadId = getPartitionThreadId(partitionId, threadCount);
        Thread thread = threads[threadId];
        OperationRunner runner = partitionOperationRunners[partitionId];
        runner.setCurrentThread(thread);
    }
    return threads;
}
Also used : InboundResponseHandlerSupplier.getIdleStrategy(com.hazelcast.spi.impl.operationservice.impl.InboundResponseHandlerSupplier.getIdleStrategy) IdleStrategy(com.hazelcast.internal.util.concurrent.IdleStrategy) MPSCQueue(com.hazelcast.internal.util.concurrent.MPSCQueue) OperationHostileThread(com.hazelcast.spi.impl.operationexecutor.OperationHostileThread) OperationRunner(com.hazelcast.spi.impl.operationexecutor.OperationRunner)

Example 2 with IdleStrategy

use of com.hazelcast.internal.util.concurrent.IdleStrategy in project hazelcast by hazelcast.

the class TestSupport method runTest.

private void runTest(TestMode testMode) throws Exception {
    beforeEachRun.run();
    assert testMode.isSnapshotsEnabled() || testMode.snapshotRestoreInterval() == 0 : "Illegal combination: don't do snapshots, but do restore";
    boolean doSnapshots = testMode.doSnapshots;
    int doRestoreEvery = testMode.restoreInterval;
    IdleStrategy idler = new BackoffIdleStrategy(0, 0, MICROSECONDS.toNanos(1), MILLISECONDS.toNanos(1));
    int idleCount = 0;
    System.out.println("### Running the test, mode=" + testMode.toString());
    TestInbox inbox = new TestInbox();
    int inboxOrdinal = -1;
    Processor[] processor = { newProcessorFromSupplier() };
    boolean isCooperative = processor[0].isCooperative();
    // we'll use 1-capacity outbox to test outbox rejection
    TestOutbox[] outbox = { createOutbox() };
    List<List<Object>> actualOutputs = new ArrayList<>(outputOrdinalCount);
    for (int i = 0; i < outputOrdinalCount; i++) {
        actualOutputs.add(new ArrayList<>());
    }
    // create instance of your processor and call the init() method
    initProcessor(processor[0], outbox[0]);
    int[] restoreCount = { 0 };
    // do snapshot+restore before processing any item. This will test saveToSnapshot() in this edge case
    snapshotAndRestore(processor, outbox, actualOutputs, doSnapshots, doRestoreEvery, restoreCount);
    // call the process() method
    List<ObjectWithOrdinal> input = mixInputs(inputs, priorities);
    int inputPosition = 0;
    while (inputPosition < input.size() || !inbox.isEmpty()) {
        if (inbox.isEmpty() && inputPosition < input.size()) {
            inboxOrdinal = input.get(inputPosition).ordinal;
            for (int added = 0; inputPosition < input.size() && added < testMode.inboxLimit() && inboxOrdinal == input.get(inputPosition).ordinal && (added == 0 || !(input.get(inputPosition).item instanceof Watermark)); added++) {
                ObjectWithOrdinal objectWithOrdinal = input.get(inputPosition++);
                inbox.queue().add(objectWithOrdinal.item);
                inboxOrdinal = objectWithOrdinal.ordinal;
            }
            if (logInputOutput) {
                System.out.println(LocalTime.now() + " Input-" + inboxOrdinal + ": " + inbox);
            }
        }
        int lastInboxSize = inbox.size();
        String methodName;
        methodName = processInbox(inbox, inboxOrdinal, isCooperative, processor);
        boolean madeProgress = inbox.size() < lastInboxSize || (outbox[0].bucketCount() > 0 && !outbox[0].queue(0).isEmpty());
        assertTrue(methodName + "() call without progress", !assertProgress || madeProgress);
        idleCount = idle(idler, idleCount, madeProgress);
        if (outbox[0].bucketCount() > 0 && outbox[0].queue(0).size() == 1 && !inbox.isEmpty()) {
            // if the outbox is full, call the process() method again. Cooperative
            // processor must be able to cope with this situation and not try to put
            // more items to the outbox.
            outbox[0].reset();
            processInbox(inbox, inboxOrdinal, isCooperative, processor);
        }
        outbox[0].drainQueuesAndReset(actualOutputs, logInputOutput);
        if (inbox.isEmpty()) {
            snapshotAndRestore(processor, outbox, actualOutputs, doSnapshots, doRestoreEvery, restoreCount);
        }
    }
    if (logInputOutput && !inputs.isEmpty()) {
        System.out.println(LocalTime.now() + " Input processed, calling complete()");
    }
    // call the complete() method
    if (callComplete) {
        long completeStart = System.nanoTime();
        long outputMatchedAt = Long.MAX_VALUE;
        boolean[] done = { false };
        do {
            doCall("complete", isCooperative, () -> done[0] = processor[0].complete());
            boolean madeProgress = done[0] || (outbox[0].bucketCount() > 0 && !outbox[0].queue(0).isEmpty());
            assertTrue("complete() call without progress", !assertProgress || madeProgress);
            outbox[0].drainQueuesAndReset(actualOutputs, logInputOutput);
            if (outbox[0].hasUnfinishedItem()) {
                assertFalse("outbox has unfinished items, but complete() claims to be done", done[0]);
                outbox[0].block();
            } else {
                outbox[0].unblock();
                snapshotAndRestore(processor, outbox, actualOutputs, madeProgress && doSnapshots && !done[0], doRestoreEvery, restoreCount);
            }
            idleCount = idle(idler, idleCount, madeProgress);
            long now = System.nanoTime();
            if (runUntilOutputMatchesTimeoutMillis >= 0) {
                try {
                    assertOutputFn.accept(testMode, actualOutputs);
                    outputMatchedAt = Math.min(outputMatchedAt, now);
                } catch (AssertionError e) {
                    if (outputMatchedAt < Long.MAX_VALUE) {
                        throw new AssertionError("the output already matched, but doesn't match now", e);
                    }
                // ignore the failure otherwise and continue calling complete()
                }
                long elapsedSinceStart = NANOSECONDS.toMillis(now - completeStart);
                long elapsedSinceMatch = NANOSECONDS.toMillis(subtractClamped(now, outputMatchedAt));
                if (elapsedSinceStart > runUntilOutputMatchesTimeoutMillis || elapsedSinceMatch > runUntilOutputMatchesExtraTimeMillis) {
                    break;
                }
            }
        } while (!done[0]);
        assertTrue("complete returned true in a run-until-output-matches mode", !done[0] || runUntilOutputMatchesTimeoutMillis <= 0);
    }
    processor[0].close();
    assertOutputFn.accept(testMode, actualOutputs);
}
Also used : Processor(com.hazelcast.jet.core.Processor) BackoffIdleStrategy(com.hazelcast.internal.util.concurrent.BackoffIdleStrategy) IdleStrategy(com.hazelcast.internal.util.concurrent.IdleStrategy) ArrayList(java.util.ArrayList) BackoffIdleStrategy(com.hazelcast.internal.util.concurrent.BackoffIdleStrategy) ArrayList(java.util.ArrayList) Collections.singletonList(java.util.Collections.singletonList) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) Watermark(com.hazelcast.jet.core.Watermark)

Aggregations

IdleStrategy (com.hazelcast.internal.util.concurrent.IdleStrategy)2 BackoffIdleStrategy (com.hazelcast.internal.util.concurrent.BackoffIdleStrategy)1 MPSCQueue (com.hazelcast.internal.util.concurrent.MPSCQueue)1 Processor (com.hazelcast.jet.core.Processor)1 Watermark (com.hazelcast.jet.core.Watermark)1 OperationHostileThread (com.hazelcast.spi.impl.operationexecutor.OperationHostileThread)1 OperationRunner (com.hazelcast.spi.impl.operationexecutor.OperationRunner)1 InboundResponseHandlerSupplier.getIdleStrategy (com.hazelcast.spi.impl.operationservice.impl.InboundResponseHandlerSupplier.getIdleStrategy)1 ArrayList (java.util.ArrayList)1 Collections.emptyList (java.util.Collections.emptyList)1 Collections.singletonList (java.util.Collections.singletonList)1 List (java.util.List)1