Java Code Examples for org.agrona.concurrent.IdleStrategy#idle()

The following examples show how to use org.agrona.concurrent.IdleStrategy#idle() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SamplesUtil.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Return a reusable, parametrised event loop that calls and idler when no messages are received.
 *
 * @param fragmentHandler to be called back for each message.
 * @param limit           passed to {@link Subscription#poll(FragmentHandler, int)}.
 * @param running         indication for loop.
 * @param idleStrategy    to use for loop.
 * @return loop function.
 */
public static Consumer<Subscription> subscriberLoop(
    final FragmentHandler fragmentHandler,
    final int limit,
    final AtomicBoolean running,
    final IdleStrategy idleStrategy)
{
    return
        (subscription) ->
        {
            final FragmentAssembler assembler = new FragmentAssembler(fragmentHandler);
            while (running.get())
            {
                final int fragmentsRead = subscription.poll(assembler, limit);
                idleStrategy.idle(fragmentsRead);
            }
        };
}
 
Example 2
Source File: ReplayIndexTest.java    From artio with Apache License 2.0 6 votes vote down vote up
private int query(
    final long sessionId,
    final int beginSequenceNumber,
    final int beginSequenceIndex,
    final int endSequenceNumber,
    final int endSequenceIndex)
{
    final ReplayOperation operation = query.query(
        sessionId,
        beginSequenceNumber,
        beginSequenceIndex,
        endSequenceNumber,
        endSequenceIndex,
        REPLAY,
        new FixMessageTracker(REPLAY, mockHandler, sessionId));

    final IdleStrategy idleStrategy = CommonConfiguration.backoffIdleStrategy();
    while (!operation.attemptReplay())
    {
        idleStrategy.idle();
    }
    idleStrategy.reset();

    return operation.replayedMessages();
}
 
Example 3
Source File: AeronExclusiveIpcBenchmark.java    From benchmarks with Apache License 2.0 6 votes vote down vote up
public void run()
{
    while (!subscription.isConnected())
    {
        Thread.yield();
    }

    final IdleStrategy idleStrategy = new BusySpinIdleStrategy();
    while (true)
    {
        final int frameCount = subscription.poll(this, FRAGMENT_LIMIT);
        if (0 == frameCount)
        {
            if (!running.get())
            {
                break;
            }
        }

        idleStrategy.idle(frameCount);
    }
}
 
Example 4
Source File: ImageRateSubscriber.java    From aeron with Apache License 2.0 5 votes vote down vote up
public void run()
{
    while (!subscription.isConnected())
    {
        Thread.yield();
    }

    final Image image = subscription.images().get(0);
    final ImageFragmentAssembler fragmentAssembler = new ImageFragmentAssembler(this::onFragment);
    final IdleStrategy idleStrategy = SampleConfiguration.newIdleStrategy();
    final int fragmentLimit = this.fragmentLimit;

    long failedPolls = 0;
    long successfulPolls = 0;

    while (running.get())
    {
        final int fragmentsRead = image.poll(fragmentAssembler, fragmentLimit);
        if (0 == fragmentsRead)
        {
            ++failedPolls;
        }
        else
        {
            ++successfulPolls;
        }

        idleStrategy.idle(fragmentsRead);
    }

    final double failureRatio = failedPolls / (double)(successfulPolls + failedPolls);
    System.out.format("Subscriber poll failure ratio: %f%n", failureRatio);
}
 
Example 5
Source File: IndexedReplicatedRecording.java    From aeron with Apache License 2.0 5 votes vote down vote up
public void run()
{
    while (!subscription.isConnected() || !publication.isConnected())
    {
        try
        {
            Thread.sleep(1);
        }
        catch (final InterruptedException ignore)
        {
            Thread.currentThread().interrupt();
            return;
        }
    }

    final Image image = subscription.imageBySessionId(sessionId);
    this.image = image;
    if (null == image)
    {
        throw new IllegalStateException("session not found");
    }

    lastMessagePosition = image.joinPosition();

    final IdleStrategy idleStrategy = YieldingIdleStrategy.INSTANCE;
    while (true)
    {
        final int fragments = image.controlledPoll(this, FRAGMENT_LIMIT);
        if (0 == fragments)
        {
            if (Thread.interrupted() || image.isClosed())
            {
                return;
            }
        }

        idleStrategy.idle(fragments);
    }
}
 
Example 6
Source File: ClusterTests.java    From aeron with Apache License 2.0 5 votes vote down vote up
public static Thread startMessageThread(final TestCluster cluster, final long backoffIntervalNs)
{
    final Thread thread = new Thread(
        () ->
        {
            final IdleStrategy idleStrategy = YieldingIdleStrategy.INSTANCE;
            final AeronCluster client = cluster.client();
            final ExpandableArrayBuffer msgBuffer = cluster.msgBuffer();
            msgBuffer.putStringWithoutLengthAscii(0, HELLO_WORLD_MSG);

            while (!Thread.interrupted())
            {
                if (client.offer(msgBuffer, 0, HELLO_WORLD_MSG.length()) < 0)
                {
                    LockSupport.parkNanos(backoffIntervalNs);
                }

                idleStrategy.idle(client.pollEgress());
            }
        });

    thread.setDaemon(true);
    thread.setName("message-thread");
    thread.start();

    return thread;
}
 
Example 7
Source File: AeronUtil.java    From deeplearning4j with Apache License 2.0 5 votes vote down vote up
/**
 * Return a reusable, parameterized event
 * loop that calls and idler
 * when no messages are received
 *
 * @param fragmentHandler to be called back for each message.
 * @param limit           passed to {@link Subscription#poll(FragmentHandler, int)}
 * @param running         indication for loop
 * @param idleStrategy    to use for loop
 * @return loop function
 */
public static Consumer<Subscription> subscriberLoop(final FragmentHandler fragmentHandler, final int limit,
                final AtomicBoolean running, final IdleStrategy idleStrategy, final AtomicBoolean launched) {
    return (subscription) -> {
        try {
            while (running.get()) {
                idleStrategy.idle(subscription.poll(fragmentHandler, limit));
                launched.set(true);
            }
        } catch (final Exception ex) {
            LangUtil.rethrowUnchecked(ex);
        }
    };
}
 
Example 8
Source File: EmbeddedExclusiveBufferClaimIpcThroughput.java    From aeron with Apache License 2.0 5 votes vote down vote up
public void run()
{
    final IdleStrategy idleStrategy = SampleConfiguration.newIdleStrategy();
    final AtomicBoolean running = this.running;
    final Publication publication = this.publication;
    final BufferClaim bufferClaim = new BufferClaim();
    long backPressureCount = 0;
    long totalMessageCount = 0;

    outputResults:
    while (running.get())
    {
        for (int i = 0; i < BURST_LENGTH; i++)
        {
            idleStrategy.reset();
            while (publication.tryClaim(MESSAGE_LENGTH, bufferClaim) <= 0)
            {
                ++backPressureCount;
                if (!running.get())
                {
                    break outputResults;
                }
                idleStrategy.idle();
            }

            final int offset = bufferClaim.offset();
            bufferClaim.buffer().putInt(offset, i); // Example field write
            // Real app would write whatever fields are required via a flyweight like SBE

            bufferClaim.commit();

            ++totalMessageCount;
        }
    }

    final double backPressureRatio = backPressureCount / (double)totalMessageCount;
    System.out.format("Publisher back pressure ratio: %f%n", backPressureRatio);
}
 
Example 9
Source File: EmbeddedRecordingThroughput.java    From aeron with Apache License 2.0 4 votes vote down vote up
public long streamMessagesForRecording()
{
    try (ExclusivePublication publication = aeron.addExclusivePublication(CHANNEL, STREAM_ID))
    {
        final IdleStrategy idleStrategy = YieldingIdleStrategy.INSTANCE;
        while (!publication.isConnected())
        {
            idleStrategy.idle();
        }

        final long startNs = System.nanoTime();
        final UnsafeBuffer buffer = this.buffer;

        for (long i = 0; i < NUMBER_OF_MESSAGES; i++)
        {
            buffer.putLong(0, i);

            idleStrategy.reset();
            while (publication.offer(buffer, 0, MESSAGE_LENGTH) < 0)
            {
                idleStrategy.idle();
            }
        }

        final long stopPosition = publication.position();
        final CountersReader counters = aeron.countersReader();
        final int counterId = RecordingPos.findCounterIdBySession(counters, publication.sessionId());

        idleStrategy.reset();
        while (counters.getCounterValue(counterId) < stopPosition)
        {
            idleStrategy.idle();
        }

        final long durationMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
        final double dataRate = (stopPosition * 1000.0d / durationMs) / MEGABYTE;
        final double recordingMb = stopPosition / MEGABYTE;
        final long msgRate = (NUMBER_OF_MESSAGES / durationMs) * 1000L;

        System.out.printf(
            "Recorded %.02f MB @ %.02f MB/s - %,d msg/sec - %d byte payload + 32 byte header%n",
            recordingMb, dataRate, msgRate, MESSAGE_LENGTH);

        return RecordingPos.getRecordingId(counters, counterId);
    }
}
 
Example 10
Source File: BenchServer.java    From rpc-bench with Apache License 2.0 4 votes vote down vote up
private void execute() {
  final IdleStrategy idleStrategy = new BusySpinIdleStrategy();
  while (running.get()) {
    idleStrategy.idle(subscription.poll(fragmentHandler, FRAGMENT_LIMIT));
  }
}
 
Example 11
Source File: Tests.java    From aeron with Apache License 2.0 4 votes vote down vote up
public static void wait(final IdleStrategy idleStrategy, final String message)
{
    idleStrategy.idle();
    checkInterruptStatus(message);
}
 
Example 12
Source File: Tests.java    From aeron with Apache License 2.0 4 votes vote down vote up
public static void wait(final IdleStrategy idleStrategy, final String format, final Object... params)
{
    idleStrategy.idle();
    checkInterruptStatus(format, params);
}
 
Example 13
Source File: Tests.java    From aeron with Apache License 2.0 4 votes vote down vote up
public static void wait(final IdleStrategy idleStrategy, final Supplier<String> messageSupplier)
{
    idleStrategy.idle();
    checkInterruptStatus(messageSupplier);
}
 
Example 14
Source File: Pong.java    From aeron with Apache License 2.0 4 votes vote down vote up
public static void main(final String[] args)
{
    final MediaDriver driver = EMBEDDED_MEDIA_DRIVER ? MediaDriver.launchEmbedded() : null;

    final Aeron.Context ctx = new Aeron.Context();
    if (EMBEDDED_MEDIA_DRIVER)
    {
        ctx.aeronDirectoryName(driver.aeronDirectoryName());
    }

    if (INFO_FLAG)
    {
        ctx.availableImageHandler(SamplesUtil::printAvailableImage);
        ctx.unavailableImageHandler(SamplesUtil::printUnavailableImage);
    }

    final IdleStrategy idleStrategy = new BusySpinIdleStrategy();

    System.out.println("Subscribing Ping at " + PING_CHANNEL + " on stream id " + PING_STREAM_ID);
    System.out.println("Publishing Pong at " + PONG_CHANNEL + " on stream id " + PONG_STREAM_ID);
    System.out.println("Using exclusive publications " + EXCLUSIVE_PUBLICATIONS);

    final AtomicBoolean running = new AtomicBoolean(true);
    SigInt.register(() -> running.set(false));

    try (Aeron aeron = Aeron.connect(ctx);
        Subscription subscription = aeron.addSubscription(PING_CHANNEL, PING_STREAM_ID);
        Publication publication = EXCLUSIVE_PUBLICATIONS ?
            aeron.addExclusivePublication(PONG_CHANNEL, PONG_STREAM_ID) :
            aeron.addPublication(PONG_CHANNEL, PONG_STREAM_ID))
    {
        final BufferClaim bufferClaim = new BufferClaim();
        final FragmentHandler fragmentHandler = (buffer, offset, length, header) ->
            pingHandler(bufferClaim, publication, buffer, offset, length, header);

        while (running.get())
        {
            idleStrategy.idle(subscription.poll(fragmentHandler, FRAME_COUNT_LIMIT));
        }

        System.out.println("Shutting down...");
    }

    CloseHelper.quietClose(driver);
}
 
Example 15
Source File: StreamingPublisher.java    From aeron with Apache License 2.0 4 votes vote down vote up
public static void main(final String[] args) throws Exception
{
    if (MESSAGE_LENGTH < SIZE_OF_LONG)
    {
        throw new IllegalArgumentException("Message length must be at least " + SIZE_OF_LONG + " bytes");
    }

    final MediaDriver driver = EMBEDDED_MEDIA_DRIVER ? MediaDriver.launchEmbedded() : null;
    final Aeron.Context context = new Aeron.Context();

    if (EMBEDDED_MEDIA_DRIVER)
    {
        context.aeronDirectoryName(driver.aeronDirectoryName());
    }

    final RateReporter reporter = new RateReporter(TimeUnit.SECONDS.toNanos(1), StreamingPublisher::printRate);
    final ExecutorService executor = Executors.newFixedThreadPool(1);

    executor.execute(reporter);

    // Connect to media driver and add publication to send messages on the configured channel and stream ID.
    // The Aeron and Publication classes implement AutoCloseable, and will automatically
    // clean up resources when this try block is finished.
    try (Aeron aeron = Aeron.connect(context);
        Publication publication = aeron.addPublication(CHANNEL, STREAM_ID))
    {
        final ContinueBarrier barrier = new ContinueBarrier("Execute again?");
        final IdleStrategy idleStrategy = SampleConfiguration.newIdleStrategy();

        do
        {
            printingActive = true;

            System.out.format(
                "%nStreaming %,d messages of%s size %d bytes to %s on stream id %d%n",
                NUMBER_OF_MESSAGES,
                RANDOM_MESSAGE_LENGTH ? " random" : "",
                MESSAGE_LENGTH,
                CHANNEL,
                STREAM_ID);

            long backPressureCount = 0;

            for (long i = 0; i < NUMBER_OF_MESSAGES; i++)
            {
                final int length = LENGTH_GENERATOR.getAsInt();

                OFFER_BUFFER.putLong(0, i);
                idleStrategy.reset();
                while (publication.offer(OFFER_BUFFER, 0, length, null) < 0L)
                {
                    // The offer failed, which is usually due to the publication
                    // being temporarily blocked.  Retry the offer after a short
                    // spin/yield/sleep, depending on the chosen IdleStrategy.
                    backPressureCount++;
                    idleStrategy.idle();
                }

                reporter.onMessage(length);
            }

            System.out.println(
                "Done streaming. Back pressure ratio " + ((double)backPressureCount / NUMBER_OF_MESSAGES));

            if (LINGER_TIMEOUT_MS > 0)
            {
                System.out.println("Lingering for " + LINGER_TIMEOUT_MS + " milliseconds...");
                Thread.sleep(LINGER_TIMEOUT_MS);
            }

            printingActive = false;
        }
        while (barrier.await());
    }

    reporter.halt();
    executor.shutdown();
    CloseHelper.quietClose(driver);
}
 
Example 16
Source File: MemoryOrderingTest.java    From aeron with Apache License 2.0 4 votes vote down vote up
@Test
@Timeout(10)
public void shouldReceiveMessagesInOrderWithFirstLongWordIntact() throws Exception
{
    final UnsafeBuffer srcBuffer = new UnsafeBuffer(ByteBuffer.allocate(MESSAGE_LENGTH));
    srcBuffer.setMemory(0, MESSAGE_LENGTH, (byte)7);

    try (Subscription subscription = aeron.addSubscription(CHANNEL, STREAM_ID);
        Publication publication = aeron.addPublication(CHANNEL, STREAM_ID))
    {
        final IdleStrategy idleStrategy = YieldingIdleStrategy.INSTANCE;
        final Thread subscriberThread = new Thread(new Subscriber(subscription));
        subscriberThread.setDaemon(true);
        subscriberThread.start();

        for (int i = 0; i < NUM_MESSAGES; i++)
        {
            if (null != failedMessage)
            {
                fail(failedMessage);
            }

            srcBuffer.putLong(0, i);

            while (publication.offer(srcBuffer) < 0L)
            {
                if (null != failedMessage)
                {
                    fail(failedMessage);
                }

                idleStrategy.idle();
                Tests.checkInterruptStatus();
            }

            if (i % BURST_LENGTH == 0)
            {
                final long timeoutNs = System.nanoTime() + INTER_BURST_DURATION_NS;
                long nowNs;
                do
                {
                    nowNs = System.nanoTime();
                }
                while ((timeoutNs - nowNs) > 0);
            }
        }

        subscriberThread.join();
    }
}
 
Example 17
Source File: EmbeddedExclusiveSpiedThroughput.java    From aeron with Apache License 2.0 4 votes vote down vote up
public static void main(final String[] args) throws Exception
{
    loadPropertiesFiles(args);

    final RateReporter reporter = new RateReporter(
        TimeUnit.SECONDS.toNanos(1), EmbeddedExclusiveSpiedThroughput::printRate);
    final ExecutorService executor = Executors.newFixedThreadPool(2);
    final AtomicBoolean running = new AtomicBoolean(true);

    final MediaDriver.Context ctx = new MediaDriver.Context()
        .spiesSimulateConnection(true);

    try (MediaDriver ignore = MediaDriver.launch(ctx);
        Aeron aeron = Aeron.connect();
        Subscription subscription = aeron.addSubscription(CommonContext.SPY_PREFIX + CHANNEL, STREAM_ID);
        ExclusivePublication publication = aeron.addExclusivePublication(CHANNEL, STREAM_ID))
    {
        executor.execute(reporter);
        executor.execute(() -> SamplesUtil.subscriberLoop(
            rateReporterHandler(reporter), FRAGMENT_COUNT_LIMIT, running).accept(subscription));

        final ContinueBarrier barrier = new ContinueBarrier("Execute again?");
        final IdleStrategy idleStrategy = SampleConfiguration.newIdleStrategy();

        do
        {
            System.out.format(
                "%nStreaming %,d messages of payload length %d bytes to %s on stream id %d%n",
                NUMBER_OF_MESSAGES, MESSAGE_LENGTH, CHANNEL, STREAM_ID);

            printingActive = true;

            long backPressureCount = 0;
            for (long i = 0; i < NUMBER_OF_MESSAGES; i++)
            {
                OFFER_BUFFER.putLong(0, i);

                idleStrategy.reset();
                while (publication.offer(OFFER_BUFFER, 0, MESSAGE_LENGTH, null) < 0)
                {
                    backPressureCount++;
                    idleStrategy.idle();
                }
            }

            System.out.println(
                "Done streaming. backPressureRatio=" + ((double)backPressureCount / NUMBER_OF_MESSAGES));

            if (LINGER_TIMEOUT_MS > 0)
            {
                System.out.println("Lingering for " + LINGER_TIMEOUT_MS + " milliseconds...");
                Thread.sleep(LINGER_TIMEOUT_MS);
            }

            printingActive = false;
        }
        while (barrier.await());

        running.set(false);
        reporter.halt();
        executor.shutdown();
    }
}
 
Example 18
Source File: SampleServer.java    From artio with Apache License 2.0 4 votes vote down vote up
public static void main(final String[] args)
{
    final MessageValidationStrategy validationStrategy = MessageValidationStrategy.targetCompId(ACCEPTOR_COMP_ID)
        .and(MessageValidationStrategy.senderCompId(Collections.singletonList(INITIATOR_COMP_ID)));

    final AuthenticationStrategy authenticationStrategy = AuthenticationStrategy.of(validationStrategy);

    // Static configuration lasts the duration of a FIX-Gateway instance
    final String aeronChannel = "aeron:udp?endpoint=localhost:10000";
    final EngineConfiguration configuration = new EngineConfiguration()
        .bindTo("localhost", 9999)
        .libraryAeronChannel(aeronChannel);
    configuration.authenticationStrategy(authenticationStrategy);

    cleanupOldLogFileDir(configuration);

    final Context context = new Context()
        .threadingMode(SHARED)
        .dirDeleteOnStart(true);

    final Archive.Context archiveContext = new Archive.Context()
        .threadingMode(ArchiveThreadingMode.SHARED)
        .deleteArchiveOnStart(true);

    try (ArchivingMediaDriver driver = ArchivingMediaDriver.launch(context, archiveContext);
        FixEngine gateway = FixEngine.launch(configuration))
    {
        final LibraryConfiguration libraryConfiguration = new LibraryConfiguration();

        // You register the new session handler - which is your application hook
        // that receives messages for new sessions
        libraryConfiguration
            .sessionAcquireHandler((session, acquiredInfo) -> onConnect(session))
            .sessionExistsHandler(new AcquiringSessionExistsHandler())
            .libraryAeronChannels(singletonList(aeronChannel));

        final IdleStrategy idleStrategy = CommonConfiguration.backoffIdleStrategy();

        try (FixLibrary library = SampleUtil.blockingConnect(libraryConfiguration))
        {
            final AtomicBoolean running = new AtomicBoolean(true);
            SigInt.register(() -> running.set(false));

            while (running.get())
            {
                idleStrategy.idle(library.poll(1));

                if (session != null && session.state() == DISCONNECTED)
                {
                    break;
                }
            }
        }
    }

    System.exit(0);
}
 
Example 19
Source File: StressUtil.java    From artio with Apache License 2.0 4 votes vote down vote up
static void exchangeMessages(
    final FixLibrary library,
    final Session session,
    final IdleStrategy idleStrategy,
    final TestReqIdFinder testReqIdFinder,
    final String[] messagePool,
    final Random random,
    final String senderCompId)
{
    final TestRequestEncoder testRequest = new TestRequestEncoder();

    for (int j = 0; j < MESSAGES_EXCHANGED; j++)
    {
        if (!StressConfiguration.PRINT_EXCHANGE)
        {
            System.out.format("\rMessage %d", j);
        }

        final String msg = messagePool[random.nextInt(messagePool.length)];
        testRequest.testReqID(msg);

        while (session.trySend(testRequest) < 0)
        {
            idleStrategy.idle(library.poll(1));
        }

        for (long fails = 0; !msg.equals(testReqIdFinder.testReqId()); fails++)
        {
            if (StressConfiguration.printFailedSpints(fails))
            {
                System.out.println(senderCompId + " Has repeatedly failed for " + msg);
                fails = 0;
            }

            idleStrategy.idle(library.poll(1));
        }

        if (StressConfiguration.PRINT_EXCHANGE)
        {
            System.out.println(senderCompId + " Success, received reply! " + msg);
        }
    }

    if (!StressConfiguration.PRINT_EXCHANGE)
    {
        System.out.format("\r");
    }
}
 
Example 20
Source File: EmbeddedExclusiveThroughput.java    From aeron with Apache License 2.0 4 votes vote down vote up
public static void main(final String[] args) throws Exception
{
    loadPropertiesFiles(args);

    final RateReporter reporter = new RateReporter(
        TimeUnit.SECONDS.toNanos(1), EmbeddedExclusiveThroughput::printRate);
    final ExecutorService executor = Executors.newFixedThreadPool(2);
    final AtomicBoolean running = new AtomicBoolean(true);

    try (MediaDriver ignore = MediaDriver.launch();
        Aeron aeron = Aeron.connect();
        Subscription subscription = aeron.addSubscription(CHANNEL, STREAM_ID);
        ExclusivePublication publication = aeron.addExclusivePublication(CHANNEL, STREAM_ID))
    {
        executor.execute(reporter);
        executor.execute(() -> SamplesUtil.subscriberLoop(
            rateReporterHandler(reporter), FRAGMENT_COUNT_LIMIT, running).accept(subscription));

        final ContinueBarrier barrier = new ContinueBarrier("Execute again?");
        final IdleStrategy idleStrategy = SampleConfiguration.newIdleStrategy();

        do
        {
            System.out.format(
                "%nStreaming %,d messages of payload length %d bytes to %s on stream id %d%n",
                NUMBER_OF_MESSAGES, MESSAGE_LENGTH, CHANNEL, STREAM_ID);

            printingActive = true;

            long backPressureCount = 0;
            for (long i = 0; i < NUMBER_OF_MESSAGES; i++)
            {
                OFFER_BUFFER.putLong(0, i);

                idleStrategy.reset();
                while (publication.offer(OFFER_BUFFER, 0, MESSAGE_LENGTH, null) < 0)
                {
                    backPressureCount++;
                    idleStrategy.idle();
                }
            }

            System.out.println(
                "Done streaming. backPressureRatio=" + ((double)backPressureCount / NUMBER_OF_MESSAGES));

            if (LINGER_TIMEOUT_MS > 0)
            {
                System.out.println("Lingering for " + LINGER_TIMEOUT_MS + " milliseconds...");
                Thread.sleep(LINGER_TIMEOUT_MS);
            }

            printingActive = false;
        }
        while (barrier.await());

        running.set(false);
        reporter.halt();
        executor.shutdown();
    }
}