org.agrona.concurrent.status.CountersReader Java Examples

The following examples show how to use org.agrona.concurrent.status.CountersReader. 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
/**
 * Map an existing CnC file.
 *
 * @return the {@link CountersReader} over the CnC file.
 */
public static CountersReader mapCounters()
{
    final File cncFile = CommonContext.newDefaultCncFile();
    System.out.println("Command `n Control file " + cncFile);

    final MappedByteBuffer cncByteBuffer = mapExistingFileReadOnly(cncFile);
    final DirectBuffer cncMetaData = createMetaDataBuffer(cncByteBuffer);
    final int cncVersion = cncMetaData.getInt(cncVersionOffset(0));

    checkVersion(cncVersion);

    return new CountersReader(
        createCountersMetaDataBuffer(cncByteBuffer, cncMetaData),
        createCountersValuesBuffer(cncByteBuffer, cncMetaData));
}
 
Example #2
Source File: TestNode.java    From aeron with Apache License 2.0 6 votes vote down vote up
long appendPosition()
{
    final long recordingId = consensusModule().context().recordingLog().findLastTermRecordingId();
    if (RecordingPos.NULL_RECORDING_ID == recordingId)
    {
        fail("no recording for last term");
    }

    final CountersReader countersReader = countersReader();
    final int counterId = RecordingPos.findCounterIdByRecording(countersReader, recordingId);
    if (NULL_VALUE == counterId)
    {
        fail("recording not active " + recordingId);
    }

    return countersReader.getCounterValue(counterId);
}
 
Example #3
Source File: RecordingPos.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Find the active counter id for a stream based on the session id.
 *
 * @param countersReader to search within.
 * @param sessionId      for the active recording.
 * @return the counter id if found otherwise {@link CountersReader#NULL_COUNTER_ID}.
 */
public static int findCounterIdBySession(final CountersReader countersReader, final int sessionId)
{
    final DirectBuffer buffer = countersReader.metaDataBuffer();

    for (int i = 0, size = countersReader.maxCounterId(); i < size; i++)
    {
        if (countersReader.getCounterState(i) == RECORD_ALLOCATED &&
            countersReader.getCounterTypeId(i) == RECORDING_POSITION_TYPE_ID)
        {
            if (buffer.getInt(CountersReader.metaDataOffset(i) + KEY_OFFSET + SESSION_ID_OFFSET) == sessionId)
            {
                return i;
            }
        }
    }

    return NULL_COUNTER_ID;
}
 
Example #4
Source File: RecordingPos.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Find the active counter id for a stream based on the recording id.
 *
 * @param countersReader to search within.
 * @param recordingId    for the active recording.
 * @return the counter id if found otherwise {@link CountersReader#NULL_COUNTER_ID}.
 */
public static int findCounterIdByRecording(final CountersReader countersReader, final long recordingId)
{
    final DirectBuffer buffer = countersReader.metaDataBuffer();

    for (int i = 0, size = countersReader.maxCounterId(); i < size; i++)
    {
        if (countersReader.getCounterState(i) == RECORD_ALLOCATED &&
            countersReader.getCounterTypeId(i) == RECORDING_POSITION_TYPE_ID)
        {
            if (buffer.getLong(CountersReader.metaDataOffset(i) + KEY_OFFSET + RECORDING_ID_OFFSET) == recordingId)
            {
                return i;
            }
        }
    }

    return NULL_COUNTER_ID;
}
 
Example #5
Source File: ArchiveAuthenticationTest.java    From aeron with Apache License 2.0 6 votes vote down vote up
private void createRecording()
{
    final String messagePrefix = "Message-Prefix-";
    final int messageCount = 10;

    final long subscriptionId = aeronArchive.startRecording(RECORDED_CHANNEL, RECORDED_STREAM_ID, LOCAL);

    try (Subscription subscription = aeron.addSubscription(RECORDED_CHANNEL, RECORDED_STREAM_ID);
        Publication publication = aeron.addPublication(RECORDED_CHANNEL, RECORDED_STREAM_ID))
    {
        final CountersReader counters = aeron.countersReader();
        final int counterId = Common.awaitRecordingCounterId(counters, publication.sessionId());

        offer(publication, messageCount, messagePrefix);
        consume(subscription, messageCount, messagePrefix);

        final long currentPosition = publication.position();
        awaitPosition(counters, counterId, currentPosition);
    }

    aeronArchive.stopRecording(subscriptionId);
}
 
Example #6
Source File: ReadableCounter.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Construct a view of an existing counter.
 *
 * @param countersReader for getting access to the buffers.
 * @param registrationId assigned by the driver for the counter or {@link Aeron#NULL_VALUE} if not known.
 * @param counterId      for the counter to be viewed.
 * @throws IllegalStateException if the id has for the counter has not been allocated.
 */
public ReadableCounter(final CountersReader countersReader, final long registrationId, final int counterId)
{
    final int counterState = countersReader.getCounterState(counterId);
    if (counterState != CountersReader.RECORD_ALLOCATED)
    {
        throw new IllegalStateException("Counter not allocated: id=" + counterId + " state=" + counterState);
    }

    this.countersReader = countersReader;
    this.counterId = counterId;
    this.registrationId = registrationId;

    final AtomicBuffer valuesBuffer = countersReader.valuesBuffer();
    final int counterOffset = CountersReader.counterOffset(counterId);
    valuesBuffer.boundsCheck(counterOffset, SIZE_OF_LONG);

    this.buffer = valuesBuffer.byteArray();
    this.addressOffset = valuesBuffer.addressOffset() + counterOffset;
}
 
Example #7
Source File: StatusUtil.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Return the controllable idle strategy {@link StatusIndicator}.
 *
 * @param countersReader that holds the status indicator.
 * @return status indicator to use or null if not found.
 */
public static StatusIndicator controllableIdleStrategy(final CountersReader countersReader)
{
    StatusIndicator statusIndicator = null;
    final MutableInteger id = new MutableInteger(-1);

    countersReader.forEach(
        (counterId, label) ->
        {
            if (counterId == SystemCounterDescriptor.CONTROLLABLE_IDLE_STRATEGY.id() &&
                label.equals(SystemCounterDescriptor.CONTROLLABLE_IDLE_STRATEGY.label()))
            {
                id.value = counterId;
            }
        });

    if (Aeron.NULL_VALUE != id.value)
    {
        statusIndicator = new UnsafeBufferStatusIndicator(countersReader.valuesBuffer(), id.value);
    }

    return statusIndicator;
}
 
Example #8
Source File: IndexedReplicatedRecording.java    From aeron with Apache License 2.0 6 votes vote down vote up
static void awaitPosition(final CountersReader counters, final int counterId, final long position)
    throws InterruptedException
{
    while (counters.getCounterValue(counterId) < position)
    {
        if (counters.getCounterState(counterId) != CountersReader.RECORD_ALLOCATED)
        {
            throw new IllegalStateException("count not active: " + counterId);
        }

        Thread.yield();
        if (Thread.interrupted())
        {
            throw new InterruptedException();
        }
    }
}
 
Example #9
Source File: RecoveryState.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Get the recording id of the snapshot for a service.
 *
 * @param counters  to search within.
 * @param counterId for the active recovery counter.
 * @param serviceId for the snapshot required.
 * @return the count of replay terms if found otherwise {@link Aeron#NULL_VALUE}.
 */
public static long getSnapshotRecordingId(final CountersReader counters, final int counterId, final int serviceId)
{
    final DirectBuffer buffer = counters.metaDataBuffer();

    if (counters.getCounterState(counterId) == RECORD_ALLOCATED &&
        counters.getCounterTypeId(counterId) == RECOVERY_STATE_TYPE_ID)
    {
        final int recordOffset = CountersReader.metaDataOffset(counterId);

        final int serviceCount = buffer.getInt(recordOffset + KEY_OFFSET + SERVICE_COUNT_OFFSET);
        if (serviceId < 0 || serviceId >= serviceCount)
        {
            throw new ClusterException("invalid serviceId " + serviceId + " for count of " + serviceCount);
        }

        return buffer.getLong(
            recordOffset + KEY_OFFSET + SNAPSHOT_RECORDING_IDS_OFFSET + (serviceId * SIZE_OF_LONG));
    }

    throw new ClusterException("active counter not found " + counterId);
}
 
Example #10
Source File: RecoveryState.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Find the active counter id for recovery state.
 *
 * @param counters  to search within.
 * @param clusterId to constrain the search.
 * @return the counter id if found otherwise {@link CountersReader#NULL_COUNTER_ID}.
 */
public static int findCounterId(final CountersReader counters, final int clusterId)
{
    final DirectBuffer buffer = counters.metaDataBuffer();

    for (int i = 0, size = counters.maxCounterId(); i < size; i++)
    {
        if (counters.getCounterState(i) == RECORD_ALLOCATED &&
            counters.getCounterTypeId(i) == RECOVERY_STATE_TYPE_ID)
        {
            if (buffer.getInt(CountersReader.metaDataOffset(i) + KEY_OFFSET + CLUSTER_ID_OFFSET) == clusterId)
            {
                return i;
            }
        }
    }

    return NULL_COUNTER_ID;
}
 
Example #11
Source File: ClusteredServiceAgent.java    From aeron with Apache License 2.0 6 votes vote down vote up
private long onTakeSnapshot(final long logPosition, final long leadershipTermId)
{
    final long recordingId;

    try (AeronArchive archive = AeronArchive.connect(ctx.archiveContext().clone());
        ExclusivePublication publication = aeron.addExclusivePublication(
            ctx.snapshotChannel(), ctx.snapshotStreamId()))
    {
        final String channel = ChannelUri.addSessionId(ctx.snapshotChannel(), publication.sessionId());
        archive.startRecording(channel, ctx.snapshotStreamId(), LOCAL, true);
        final CountersReader counters = aeron.countersReader();
        final int counterId = awaitRecordingCounter(publication.sessionId(), counters);
        recordingId = RecordingPos.getRecordingId(counters, counterId);

        snapshotState(publication, logPosition, leadershipTermId);
        checkForClockTick();
        service.onTakeSnapshot(publication);

        awaitRecordingComplete(recordingId, publication.position(), counters, counterId, archive);
    }

    return recordingId;
}
 
Example #12
Source File: ReplayMergeTest.java    From aeron with Apache License 2.0 6 votes vote down vote up
static void awaitPositionChange(final CountersReader counters, final int counterId, final long position)
{
    if (counters.getCounterState(counterId) != CountersReader.RECORD_ALLOCATED)
    {
        throw new IllegalStateException("count not active: " + counterId);
    }

    final long initialTimestampNs = System.nanoTime();
    final long currentPosition = counters.getCounterValue(counterId);
    do
    {
        Tests.yieldingWait(
            "publication position: %d, current position: %d, time since last change: %.6f ms",
            position, currentPosition, (System.nanoTime() - initialTimestampNs) / 1_000_000.0);
    }
    while (currentPosition == counters.getCounterValue(counterId) && currentPosition < position);
}
 
Example #13
Source File: DriverNameResolverTest.java    From aeron with Apache License 2.0 6 votes vote down vote up
private int neighborsCounterId(final String name)
{
    final CountersReader countersReader = clients.get(name).countersReader();
    final MutableInteger id = new MutableInteger(NULL_VALUE);

    countersReader.forEach(
        (counterId, typeId, keyBuffer, label) ->
        {
            if (label.startsWith("Resolver neighbors"))
            {
                id.value = counterId;
            }
        });

    return id.value;
}
 
Example #14
Source File: SetControllableIdleStrategy.java    From aeron with Apache License 2.0 6 votes vote down vote up
public static void main(final String[] args)
{
    if (args.length != 1)
    {
        System.out.format("Usage: SetControllableIdleStrategy <n>");
        System.exit(0);
    }

    try (Aeron aeron = Aeron.connect())
    {
        final CountersReader countersReader = aeron.countersReader();
        final StatusIndicator statusIndicator = StatusUtil.controllableIdleStrategy(countersReader);

        if (null != statusIndicator)
        {
            final int status = Integer.parseInt(args[0]);
            statusIndicator.setOrdered(status);
            System.out.println("Set ControllableIdleStrategy status to " + status);
        }
        else
        {
            System.out.println("Could not find ControllableIdleStrategy status.");
        }
    }
}
 
Example #15
Source File: CounterTest.java    From aeron with Apache License 2.0 6 votes vote down vote up
@Test
public void shouldBeAbleToAddCounter()
{
    final AvailableCounterHandler availableCounterHandlerClientA = mock(AvailableCounterHandler.class);
    clientA.addAvailableCounterHandler(availableCounterHandlerClientA);

    final AvailableCounterHandler availableCounterHandlerClientB = mock(AvailableCounterHandler.class);
    clientB.addAvailableCounterHandler(availableCounterHandlerClientB);

    final Counter counter = clientA.addCounter(
        COUNTER_TYPE_ID,
        null,
        0,
        0,
        labelBuffer,
        0,
        COUNTER_LABEL.length());

    assertFalse(counter.isClosed());

    verify(availableCounterHandlerClientA, timeout(5000L))
        .onAvailableCounter(any(CountersReader.class), eq(counter.registrationId()), eq(counter.id()));
    verify(availableCounterHandlerClientB, timeout(5000L))
        .onAvailableCounter(any(CountersReader.class), eq(counter.registrationId()), eq(counter.id()));
}
 
Example #16
Source File: CounterTest.java    From aeron with Apache License 2.0 6 votes vote down vote up
@Test
public void shouldBeAbleToAddReadableCounterWithinHandler()
{
    clientB.addAvailableCounterHandler(this::createReadableCounter);

    final Counter counter = clientA.addCounter(
        COUNTER_TYPE_ID,
        null,
        0,
        0,
        labelBuffer,
        0,
        COUNTER_LABEL.length());

    while (null == readableCounter)
    {
        Tests.sleep(1);
    }

    assertEquals(CountersReader.RECORD_ALLOCATED, readableCounter.state());
    assertEquals(counter.id(), readableCounter.counterId());
    assertEquals(counter.registrationId(), readableCounter.registrationId());
}
 
Example #17
Source File: ClusteredServiceAgent.java    From aeron with Apache License 2.0 6 votes vote down vote up
private void recoverState(final CountersReader counters)
{
    final int recoveryCounterId = awaitRecoveryCounter(counters);
    logPosition = RecoveryState.getLogPosition(counters, recoveryCounterId);
    clusterTime = RecoveryState.getTimestamp(counters, recoveryCounterId);
    final long leadershipTermId = RecoveryState.getLeadershipTermId(counters, recoveryCounterId);
    sessionMessageHeaderEncoder.leadershipTermId(leadershipTermId);
    isServiceActive = true;

    if (NULL_VALUE != leadershipTermId)
    {
        loadSnapshot(RecoveryState.getSnapshotRecordingId(counters, recoveryCounterId, serviceId));
    }
    else
    {
        service.onStart(this, null);
    }

    final long id = ackId++;
    idleStrategy.reset();
    while (!consensusModuleProxy.ack(logPosition, clusterTime, id, aeron.clientId(), serviceId))
    {
        idle();
    }
}
 
Example #18
Source File: CncFileReader.java    From aeron with Apache License 2.0 6 votes vote down vote up
private CncFileReader(final MappedByteBuffer cncByteBuffer)
{
    this.cncByteBuffer = cncByteBuffer;

    final DirectBuffer cncMetaDataBuffer = createMetaDataBuffer(cncByteBuffer);
    final int cncVersion = cncMetaDataBuffer.getInt(cncVersionOffset(0));

    try
    {
        checkVersion(cncVersion);
    }
    catch (final AeronException e)
    {
        IoUtil.unmap(cncByteBuffer);
        throw e;
    }

    this.cncVersion = cncVersion;
    this.cncSemanticVersion = SemanticVersion.toString(cncVersion);

    this.toDriverBuffer = CncFileDescriptor.createToDriverBuffer(cncByteBuffer, cncMetaDataBuffer);

    this.countersReader = new CountersReader(
        createCountersMetaDataBuffer(cncByteBuffer, cncMetaDataBuffer),
        createCountersValuesBuffer(cncByteBuffer, cncMetaDataBuffer));
}
 
Example #19
Source File: FlowControlTests.java    From aeron with Apache License 2.0 6 votes vote down vote up
public static void awaitConnectionAndStatusMessages(
    final CountersReader countersReader,
    final Subscription subscription,
    final Subscription... subscriptions)
{
    while (!subscription.isConnected())
    {
        Tests.sleep(1);
    }

    for (final Subscription sub : subscriptions)
    {
        while (!sub.isConnected())
        {
            Tests.sleep(1);
        }
    }

    final long delta = 1 + subscriptions.length;
    Tests.awaitCounterDelta(countersReader, STATUS_MESSAGES_RECEIVED.id(), delta);
}
 
Example #20
Source File: StatusUtil.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Return the read-only status indicator for the given receive channel URI.
 *
 * @param countersReader that holds the status indicator.
 * @param channel        for the receive channel.
 * @return read-only status indicator that can be used to query the status of the receive channel or null.
 * @see ChannelEndpointStatus for status values and indications.
 */
public static StatusIndicatorReader receiveChannelStatus(final CountersReader countersReader, final String channel)
{
    StatusIndicatorReader statusReader = null;
    final MutableInteger id = new MutableInteger(-1);

    countersReader.forEach(
        (counterId, typeId, keyBuffer, label) ->
        {
            if (typeId == ReceiveChannelStatus.RECEIVE_CHANNEL_STATUS_TYPE_ID)
            {
                if (channel.startsWith(keyBuffer.getStringAscii(ChannelEndpointStatus.CHANNEL_OFFSET)))
                {
                    id.value = counterId;
                }
            }
        });

    if (Aeron.NULL_VALUE != id.value)
    {
        statusReader = new UnsafeBufferStatusIndicator(countersReader.valuesBuffer(), id.value);
    }

    return statusReader;
}
 
Example #21
Source File: Tests.java    From aeron with Apache License 2.0 6 votes vote down vote up
public static void awaitCounterDelta(
    final CountersReader reader,
    final int counterId,
    final long initialValue,
    final long delta)
{
    final long expectedValue = initialValue + delta;
    final Supplier<String> counterMessage = () ->
        "Timed out waiting for counter '" + reader.getCounterLabel(counterId) +
        "' to increase to at least " + expectedValue;

    while (reader.getCounterValue(counterId) < expectedValue)
    {
        wait(SLEEP_1_MS, counterMessage);
    }
}
 
Example #22
Source File: ClusterControl.java    From aeron with Apache License 2.0 5 votes vote down vote up
public static void main(final String[] args)
{
    checkUsage(args);

    final ToggleState toggleState = ToggleState.valueOf(args[0].toUpperCase());

    final File cncFile = CommonContext.newDefaultCncFile();
    System.out.println("Command `n Control file " + cncFile);

    final CountersReader countersReader = mapCounters(cncFile);
    final int clusterId = ClusteredServiceContainer.Configuration.clusterId();
    final AtomicCounter controlToggle = findControlToggle(countersReader, clusterId);

    if (null == controlToggle)
    {
        System.out.println("Failed to find control toggle");
        System.exit(0);
    }

    if (toggleState.toggle(controlToggle))
    {
        System.out.println(toggleState + " toggled successfully");
    }
    else
    {
        System.out.println(toggleState + " did NOT toggle: current state=" + ToggleState.get(controlToggle));
    }
}
 
Example #23
Source File: ClusterNodeRestartTest.java    From aeron with Apache License 2.0 5 votes vote down vote up
private AtomicCounter getControlToggle()
{
    final int clusterId = container.context().clusterId();
    final CountersReader counters = container.context().aeron().countersReader();
    final AtomicCounter controlToggle = ClusterControl.findControlToggle(counters, clusterId);
    assertNotNull(controlToggle);

    return controlToggle;
}
 
Example #24
Source File: ClusteredServiceAgent.java    From aeron with Apache License 2.0 5 votes vote down vote up
private ReadableCounter awaitClusterRoleCounter(final CountersReader counters, final int clusterId)
{
    idleStrategy.reset();
    int counterId = ClusterCounters.find(counters, CLUSTER_NODE_ROLE_TYPE_ID, clusterId);
    while (NULL_COUNTER_ID == counterId)
    {
        idle();
        counterId = ClusterCounters.find(counters, CLUSTER_NODE_ROLE_TYPE_ID, clusterId);
    }

    return new ReadableCounter(counters, counterId);
}
 
Example #25
Source File: ClusteredServiceAgent.java    From aeron with Apache License 2.0 5 votes vote down vote up
private int awaitRecoveryCounter(final CountersReader counters)
{
    idleStrategy.reset();
    int counterId = RecoveryState.findCounterId(counters, ctx.clusterId());
    while (NULL_COUNTER_ID == counterId)
    {
        idle();
        counterId = RecoveryState.findCounterId(counters, ctx.clusterId());
    }

    return counterId;
}
 
Example #26
Source File: ClusteredServiceAgent.java    From aeron with Apache License 2.0 5 votes vote down vote up
public void onStart()
{
    aeron.addCloseHandler(abortHandler);
    final CountersReader counters = aeron.countersReader();
    roleCounter = awaitClusterRoleCounter(counters, ctx.clusterId());
    commitPosition = awaitCommitPositionCounter(counters, ctx.clusterId());

    recoverState(counters);
}
 
Example #27
Source File: TestCluster.java    From aeron with Apache License 2.0 5 votes vote down vote up
AtomicCounter getControlToggle(final TestNode leaderNode)
{
    final CountersReader counters = leaderNode.countersReader();
    final int clusterId = leaderNode.consensusModule().context().clusterId();
    final AtomicCounter controlToggle = ClusterControl.findControlToggle(counters, clusterId);
    assertNotNull(controlToggle);

    return controlToggle;
}
 
Example #28
Source File: LocalSocketAddressStatus.java    From aeron with Apache License 2.0 5 votes vote down vote up
/**
 * Find the list of currently bound local sockets.
 *
 * @param countersReader  for the connected driver.
 * @param channelStatus   value for the channel which aggregates the transports.
 * @param channelStatusId identity of the counter for the channel which aggregates the transports.
 * @return the list of active bound local socket addresses.
 */
public static List<String> findAddresses(
    final CountersReader countersReader, final long channelStatus, final int channelStatusId)
{
    if (channelStatus != ChannelEndpointStatus.ACTIVE)
    {
        return Collections.emptyList();
    }

    final ArrayList<String> bindings = new ArrayList<>(2);
    final DirectBuffer buffer = countersReader.metaDataBuffer();

    for (int i = 0, size = countersReader.maxCounterId(); i < size; i++)
    {
        if (countersReader.getCounterState(i) == RECORD_ALLOCATED &&
            countersReader.getCounterTypeId(i) == LOCAL_SOCKET_ADDRESS_STATUS_TYPE_ID)
        {
            final int recordOffset = CountersReader.metaDataOffset(i);
            final int keyIndex = recordOffset + CountersReader.KEY_OFFSET;

            if (channelStatusId == buffer.getInt(keyIndex + CHANNEL_STATUS_ID_OFFSET) &&
                ChannelEndpointStatus.ACTIVE == countersReader.getCounterValue(i))
            {
                final int length = buffer.getInt(keyIndex + LOCAL_SOCKET_ADDRESS_LENGTH_OFFSET);
                if (length > 0)
                {
                    bindings.add(buffer.getStringWithoutLengthAscii(
                        keyIndex + LOCAL_SOCKET_ADDRESS_STRING_OFFSET, length));
                }
            }
        }
    }

    return bindings;
}
 
Example #29
Source File: ReplayOperation.java    From artio with Apache License 2.0 5 votes vote down vote up
private boolean archivingNotComplete(final long endPosition, final long recordingId)
{
    final int counterId = RecordingPos.findCounterIdByRecording(countersReader, recordingId);

    // wait if the recording is active - otherwise assume that the recording has complete.
    if (counterId != CountersReader.NULL_COUNTER_ID)
    {
        final long counterPosition = countersReader.getCounterValue(counterId);
        return counterPosition < endPosition;
    }

    return false;
}
 
Example #30
Source File: StartFromTruncatedRecordingLogTest.java    From aeron with Apache License 2.0 5 votes vote down vote up
private void takeSnapshot(final int index)
{
    final ClusteredMediaDriver driver = clusteredMediaDrivers[index];
    final CountersReader counters = driver.consensusModule().context().aeron().countersReader();
    final int clusterId = driver.consensusModule().context().clusterId();
    final AtomicCounter controlToggle = ClusterControl.findControlToggle(counters, clusterId);

    assertNotNull(controlToggle);
    awaitNeutralCounter(index);
    assertTrue(ClusterControl.ToggleState.SNAPSHOT.toggle(controlToggle));
}