Search in sources :

Example 1 with LEADER

use of io.aeron.cluster.service.Cluster.Role.LEADER in project Aeron by real-logic.

the class ClusterTest method shouldAllowChangingTermBufferLengthAndMtuAfterRecordingLogIsTruncatedToTheLatestSnapshot.

@SuppressWarnings("MethodLength")
@Test
@InterruptAfter(30)
public void shouldAllowChangingTermBufferLengthAndMtuAfterRecordingLogIsTruncatedToTheLatestSnapshot() {
    final int originalTermLength = 256 * 1024;
    final int originalMtu = 1408;
    final int newTermLength = 2 * 1024 * 1024;
    final int newMtu = 8992;
    final CRC32 crc32 = new CRC32();
    cluster = aCluster().withStaticNodes(3).withLogChannel("aeron:udp?term-length=" + originalTermLength + "|mtu=" + originalMtu).withIngressChannel("aeron:udp?term-length=" + originalTermLength + "|mtu=" + originalMtu).withEgressChannel("aeron:udp?endpoint=localhost:0|term-length=" + originalTermLength + "|mtu=" + originalMtu).withServiceSupplier((i) -> new TestNode.TestService[] { new TestNode.TestService(), new TestNode.ChecksumService() }).start();
    systemTestWatcher.cluster(cluster);
    final TestNode leader = cluster.awaitLeader();
    for (int i = 0; i < 3; i++) {
        assertEquals(2, cluster.node(i).services().length);
    }
    cluster.connectClient();
    final int firstBatch = 9;
    int messageLength = computeMaxMessageLength(originalTermLength) - AeronCluster.SESSION_HEADER_LENGTH;
    int payloadLength = messageLength - SIZE_OF_INT;
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'x');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    int msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    long checksum = 0;
    for (int i = 0; i < firstBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
        checksum = Hashing.hash(checksum ^ msgChecksum);
    }
    cluster.awaitResponseMessageCount(firstBatch);
    cluster.takeSnapshot(leader);
    cluster.awaitSnapshotCount(1);
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'y');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    final int secondBatch = 11;
    for (int i = 0; i < secondBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
    }
    cluster.awaitResponseMessageCount(firstBatch + secondBatch);
    cluster.stopAllNodes();
    // seed all recording logs from the latest snapshot
    for (int i = 0; i < 3; i++) {
        ClusterTool.seedRecordingLogFromSnapshot(cluster.node(i).consensusModule().context().clusterDir());
    }
    cluster.logChannel("aeron:udp?term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.ingressChannel("aeron:udp?term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.egressChannel("aeron:udp?endpoint=localhost:0|term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.restartAllNodes(false);
    cluster.awaitLeader();
    assertEquals(2, cluster.followers().size());
    for (int i = 0; i < 3; i++) {
        assertEquals(2, cluster.node(i).services().length);
    }
    cluster.awaitSnapshotsLoaded();
    cluster.reconnectClient();
    messageLength = computeMaxMessageLength(newTermLength) - AeronCluster.SESSION_HEADER_LENGTH;
    payloadLength = messageLength - SIZE_OF_INT;
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'z');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    final int thirdBatch = 5;
    for (int i = 0; i < thirdBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
        checksum = Hashing.hash(checksum ^ msgChecksum);
    }
    cluster.awaitResponseMessageCount(firstBatch + secondBatch + thirdBatch);
    final int finalMessageCount = firstBatch + thirdBatch;
    final long finalChecksum = checksum;
    final Predicate<TestNode> finalServiceState = node -> {
        final TestNode.TestService[] services = node.services();
        return finalMessageCount == services[0].messageCount() && finalChecksum == ((TestNode.ChecksumService) services[1]).checksum();
    };
    for (int i = 0; i < 3; i++) {
        final TestNode node = cluster.node(i);
        cluster.awaitServiceState(node, finalServiceState);
    }
}
Also used : UNKNOWN_HOST_FILTER(io.aeron.test.SystemTestWatcher.UNKNOWN_HOST_FILTER) ClusterTests(io.aeron.test.cluster.ClusterTests) AeronCluster(io.aeron.cluster.client.AeronCluster) ControlledEgressListener(io.aeron.cluster.client.ControlledEgressListener) io.aeron.test(io.aeron.test) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) io.aeron.cluster.codecs(io.aeron.cluster.codecs) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SIZE_OF_INT(org.agrona.BitUtil.SIZE_OF_INT) FrameDescriptor.computeMaxMessageLength(io.aeron.logbuffer.FrameDescriptor.computeMaxMessageLength) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) AeronArchive(io.aeron.archive.client.AeronArchive) AuthorisationService(io.aeron.security.AuthorisationService) FOLLOWER(io.aeron.cluster.service.Cluster.Role.FOLLOWER) Publication(io.aeron.Publication) MutableInteger(org.agrona.collections.MutableInteger) EventLogExtension(io.aeron.log.EventLogExtension) MutableBoolean(org.agrona.collections.MutableBoolean) Aeron(io.aeron.Aeron) Tests.awaitAvailableWindow(io.aeron.test.Tests.awaitAvailableWindow) ControlledFragmentHandler(io.aeron.logbuffer.ControlledFragmentHandler) TestNode(io.aeron.test.cluster.TestNode) Predicate(java.util.function.Predicate) Test(org.junit.jupiter.api.Test) TimeUnit(java.util.concurrent.TimeUnit) EgressListener(io.aeron.cluster.client.EgressListener) List(java.util.List) Header(io.aeron.logbuffer.Header) Hashing(org.agrona.collections.Hashing) LITTLE_ENDIAN(java.nio.ByteOrder.LITTLE_ENDIAN) LEADER(io.aeron.cluster.service.Cluster.Role.LEADER) Assertions(org.junit.jupiter.api.Assertions) CRC32(java.util.zip.CRC32) TestCluster(io.aeron.test.cluster.TestCluster) MICROSECONDS(java.util.concurrent.TimeUnit.MICROSECONDS) DirectBuffer(org.agrona.DirectBuffer) CRC32(java.util.zip.CRC32) TestNode(io.aeron.test.cluster.TestNode) Test(org.junit.jupiter.api.Test)

Aggregations

Aeron (io.aeron.Aeron)1 Publication (io.aeron.Publication)1 AeronArchive (io.aeron.archive.client.AeronArchive)1 AeronCluster (io.aeron.cluster.client.AeronCluster)1 ControlledEgressListener (io.aeron.cluster.client.ControlledEgressListener)1 EgressListener (io.aeron.cluster.client.EgressListener)1 io.aeron.cluster.codecs (io.aeron.cluster.codecs)1 FOLLOWER (io.aeron.cluster.service.Cluster.Role.FOLLOWER)1 LEADER (io.aeron.cluster.service.Cluster.Role.LEADER)1 EventLogExtension (io.aeron.log.EventLogExtension)1 ControlledFragmentHandler (io.aeron.logbuffer.ControlledFragmentHandler)1 FrameDescriptor.computeMaxMessageLength (io.aeron.logbuffer.FrameDescriptor.computeMaxMessageLength)1 Header (io.aeron.logbuffer.Header)1 AuthorisationService (io.aeron.security.AuthorisationService)1 io.aeron.test (io.aeron.test)1 UNKNOWN_HOST_FILTER (io.aeron.test.SystemTestWatcher.UNKNOWN_HOST_FILTER)1 Tests.awaitAvailableWindow (io.aeron.test.Tests.awaitAvailableWindow)1 ClusterTests (io.aeron.test.cluster.ClusterTests)1 TestCluster (io.aeron.test.cluster.TestCluster)1 TestNode (io.aeron.test.cluster.TestNode)1