All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.aeron.test.cluster.TestBackupNode Maven / Gradle / Ivy

There is a newer version: 1.47.0
Show newest version
/*
 * Copyright 2014-2024 Real Logic Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.aeron.test.cluster;

import io.aeron.Counter;
import io.aeron.archive.Archive;
import io.aeron.archive.client.AeronArchive;
import io.aeron.cluster.ClusterBackup;
import io.aeron.cluster.ClusterTool;
import io.aeron.cluster.RecordingLog;
import io.aeron.driver.MediaDriver;
import io.aeron.test.DataCollector;
import io.aeron.test.driver.TestMediaDriver;
import org.agrona.CloseHelper;
import org.agrona.concurrent.AtomicBuffer;
import org.agrona.concurrent.EpochClock;

import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;

import static io.aeron.archive.client.AeronArchive.NULL_POSITION;

public class TestBackupNode implements AutoCloseable
{
    private final TestMediaDriver mediaDriver;
    private final Archive archive;
    private final ClusterBackup clusterBackup;
    private final int index;
    private final Context context;
    private boolean isClosed = false;

    TestBackupNode(final int index, final Context context, final DataCollector dataCollector)
    {
        this.index = index;
        this.context = context;
        try
        {
            mediaDriver = TestMediaDriver.launch(
                context.mediaDriverContext, TestCluster.clientDriverOutputConsumer(dataCollector));

            final String aeronDirectoryName = mediaDriver.context().aeronDirectoryName();
            archive = Archive.launch(context.archiveContext.aeronDirectoryName(aeronDirectoryName));

            clusterBackup = ClusterBackup.launch(context.clusterBackupContext.aeronDirectoryName(aeronDirectoryName));

            dataCollector.add(clusterBackup.context().clusterDir().toPath());
            dataCollector.add(archive.context().archiveDir().toPath());
            dataCollector.add(mediaDriver.context().aeronDirectory().toPath());
        }
        catch (final RuntimeException ex)
        {
            try
            {
                close();
            }
            catch (final Exception ex2)
            {
                ex.addSuppressed(ex2);
            }
            throw ex;
        }
    }

    public void close()
    {
        if (!isClosed)
        {
            isClosed = true;
            CloseHelper.closeAll(clusterBackup, archive, mediaDriver);
        }
    }

    boolean isClosed()
    {
        return isClosed;
    }

    ClusterBackup.State backupState()
    {
        return ClusterBackup.State.get(context.clusterBackupContext.stateCounter());
    }

    long liveLogPosition()
    {
        final Counter counter = context.clusterBackupContext.liveLogPositionCounter();
        if (counter.isClosed())
        {
            return NULL_POSITION;
        }

        return counter.get();
    }

    public EpochClock epochClock()
    {
        return context.clusterBackupContext.epochClock();
    }

    public long nextBackupQueryDeadlineMs()
    {
        return ClusterTool.nextBackupQueryDeadlineMs(context.clusterBackupContext.clusterDir());
    }

    public boolean nextBackupQueryDeadlineMs(final long delayMs)
    {
        final long nowMs = epochClock().time();

        return ClusterTool.nextBackupQueryDeadlineMs(context.clusterBackupContext.clusterDir(), nowMs + delayMs);
    }

    public AtomicBuffer clusterBackupErrorLog()
    {
        return clusterBackup.context().clusterMarkFile().errorBuffer();
    }

    long clusterBackupErrorCount()
    {
        return clusterBackup.context().errorCounter().get();
    }

    int index()
    {
        return index;
    }

    TestMediaDriver mediaDriver()
    {
        return mediaDriver;
    }

    public long recordingLogStartPosition()
    {
        try (RecordingLog recordingLog = new RecordingLog(context.clusterBackupContext.clusterDir(), false))
        {
            final long recordingId = Objects.requireNonNull(recordingLog.findLastTerm()).recordingId;

            final AeronArchive.Context backupArchiveContext = context.clusterBackupContext.archiveContext();
            try (AeronArchive aeronArchive = AeronArchive.connect(new AeronArchive.Context()
                .aeronDirectoryName(backupArchiveContext.aeronDirectoryName())
                .controlRequestChannel(backupArchiveContext.controlRequestChannel())
                .controlRequestStreamId(backupArchiveContext.controlRequestStreamId())
                .controlResponseChannel(backupArchiveContext.controlResponseChannel())
                .controlResponseStreamId(ThreadLocalRandom.current().nextInt())))
            {
                return aeronArchive.getStartPosition(recordingId);
            }
        }
    }

    static class Context
    {
        final MediaDriver.Context mediaDriverContext = new MediaDriver.Context();
        final Archive.Context archiveContext = new Archive.Context();
        final ClusterBackup.Context clusterBackupContext = new ClusterBackup.Context();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy