use of org.agrona.BitUtil.SIZE_OF_INT in project Aeron by real-logic.
the class ExclusivePublicationTest method shouldOfferTwoBuffersFromIndependentExclusivePublications.
@ParameterizedTest
@MethodSource("channels")
@InterruptAfter(10)
void shouldOfferTwoBuffersFromIndependentExclusivePublications(final String channel) {
try (Subscription subscription = aeron.addSubscription(channel, STREAM_ID);
ExclusivePublication publicationOne = aeron.addExclusivePublication(channel, STREAM_ID);
ExclusivePublication publicationTwo = aeron.addExclusivePublication(channel, STREAM_ID)) {
final int expectedNumberOfFragments = 778;
int totalFragmentsRead = 0;
final MutableInteger messageCount = new MutableInteger();
final FragmentHandler fragmentHandler = (buffer, offset, length, header) -> {
assertEquals(MESSAGE_LENGTH + SIZE_OF_INT, length);
final int publisherId = buffer.getInt(offset);
if (1 == publisherId) {
assertEquals(Byte.MIN_VALUE, buffer.getByte(offset + SIZE_OF_INT));
} else if (2 == publisherId) {
assertEquals(Byte.MAX_VALUE, buffer.getByte(offset + SIZE_OF_INT));
} else {
fail("unknown publisherId=" + publisherId);
}
messageCount.value++;
};
Tests.awaitConnections(subscription, 2);
final UnsafeBuffer pubOneHeader = new UnsafeBuffer(new byte[SIZE_OF_INT]);
pubOneHeader.putInt(0, 1);
final UnsafeBuffer pubOnePayload = new UnsafeBuffer(new byte[MESSAGE_LENGTH]);
pubOnePayload.setMemory(0, MESSAGE_LENGTH, Byte.MIN_VALUE);
final UnsafeBuffer pubTwoHeader = new UnsafeBuffer(new byte[SIZE_OF_INT]);
pubTwoHeader.putInt(0, 2);
final UnsafeBuffer pubTwoPayload = new UnsafeBuffer(new byte[MESSAGE_LENGTH]);
pubTwoPayload.setMemory(0, MESSAGE_LENGTH, Byte.MAX_VALUE);
for (int i = 0; i < expectedNumberOfFragments; i += 2) {
while (publicationOne.offer(pubOneHeader, 0, SIZE_OF_INT, pubOnePayload, 0, MESSAGE_LENGTH) < 0L) {
Tests.yield();
totalFragmentsRead += pollFragments(subscription, fragmentHandler);
}
while (publicationTwo.offer(pubTwoHeader, 0, SIZE_OF_INT, pubTwoPayload, 0, MESSAGE_LENGTH) < 0L) {
Tests.yield();
totalFragmentsRead += pollFragments(subscription, fragmentHandler);
}
totalFragmentsRead += pollFragments(subscription, fragmentHandler);
}
do {
totalFragmentsRead += pollFragments(subscription, fragmentHandler);
} while (totalFragmentsRead < expectedNumberOfFragments);
assertEquals(expectedNumberOfFragments, messageCount.value);
}
}
use of org.agrona.BitUtil.SIZE_OF_INT 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);
}
}
use of org.agrona.BitUtil.SIZE_OF_INT in project Aeron by real-logic.
the class ClusterNodeRestartTest method launchService.
private void launchService(final AtomicLong msgCounter) {
final ClusteredService service = new StubClusteredService() {
private int nextCorrelationId = 0;
private int counterValue = 0;
public void onStart(final Cluster cluster, final Image snapshotImage) {
super.onStart(cluster, snapshotImage);
if (null != snapshotImage) {
final FragmentHandler fragmentHandler = (buffer, offset, length, header) -> {
nextCorrelationId = buffer.getInt(offset);
offset += SIZE_OF_INT;
counterValue = buffer.getInt(offset);
offset += SIZE_OF_INT;
serviceState.set(buffer.getStringAscii(offset));
};
while (true) {
final int fragments = snapshotImage.poll(fragmentHandler, 1);
if (fragments == 1 || snapshotImage.isEndOfStream()) {
break;
}
idleStrategy.idle();
}
}
}
public void onSessionMessage(final ClientSession session, final long timestamp, final DirectBuffer buffer, final int offset, final int length, final Header header) {
final int sentValue = buffer.getInt(offset + MESSAGE_VALUE_OFFSET);
assertEquals(counterValue, sentValue);
counterValue++;
serviceState.set(Integer.toString(counterValue));
msgCounter.getAndIncrement();
if (TIMER_MESSAGE_LENGTH == length) {
final long correlationId = serviceCorrelationId(nextCorrelationId++);
final long deadlineMs = timestamp + buffer.getLong(offset + TIMER_MESSAGE_DELAY_OFFSET);
while (!cluster.scheduleTimer(correlationId, deadlineMs)) {
idleStrategy.idle();
}
}
}
public void onTakeSnapshot(final ExclusivePublication snapshotPublication) {
final ExpandableArrayBuffer buffer = new ExpandableArrayBuffer();
int length = 0;
buffer.putInt(length, nextCorrelationId);
length += SIZE_OF_INT;
buffer.putInt(length, counterValue);
length += SIZE_OF_INT;
length += buffer.putStringAscii(length, Integer.toString(counterValue));
snapshotPublication.offer(buffer, 0, length);
}
};
container = ClusteredServiceContainer.launch(new ClusteredServiceContainer.Context().clusteredService(service).terminationHook(ClusterTests.NOOP_TERMINATION_HOOK).errorHandler(ClusterTests.errorHandler(0)));
}
use of org.agrona.BitUtil.SIZE_OF_INT in project aeron by real-logic.
the class ClusterTimerTest method launchReschedulingService.
private void launchReschedulingService(final AtomicLong triggeredTimersCounter) {
final ClusteredService service = new StubClusteredService() {
private int timerId = 1;
public void onTimerEvent(final long correlationId, final long timestamp) {
triggeredTimersCounter.getAndIncrement();
scheduleNext(serviceCorrelationId(timerId++), timestamp + INTERVAL_MS);
}
public void onStart(final Cluster cluster, final Image snapshotImage) {
super.onStart(cluster, snapshotImage);
this.cluster = cluster;
if (null != snapshotImage) {
final FragmentHandler fragmentHandler = (buffer, offset, length, header) -> timerId = buffer.getInt(offset);
while (true) {
final int fragments = snapshotImage.poll(fragmentHandler, 1);
if (fragments == 1 || snapshotImage.isEndOfStream()) {
break;
}
idleStrategy.idle();
}
}
}
public void onTakeSnapshot(final ExclusivePublication snapshotPublication) {
final ExpandableArrayBuffer buffer = new ExpandableArrayBuffer(SIZE_OF_INT);
buffer.putInt(0, timerId);
idleStrategy.reset();
while (snapshotPublication.offer(buffer, 0, SIZE_OF_INT) < 0) {
idleStrategy.idle();
}
}
public void onNewLeadershipTermEvent(final long leadershipTermId, final long logPosition, final long timestamp, final long termBaseLogPosition, final int leaderMemberId, final int logSessionId, final TimeUnit timeUnit, final int appVersion) {
scheduleNext(serviceCorrelationId(timerId++), timestamp + INTERVAL_MS);
}
private void scheduleNext(final long correlationId, final long deadlineMs) {
idleStrategy.reset();
while (!cluster.scheduleTimer(correlationId, deadlineMs)) {
idleStrategy.idle();
}
}
};
container = ClusteredServiceContainer.launch(new ClusteredServiceContainer.Context().clusteredService(service).terminationHook(ClusterTests.NOOP_TERMINATION_HOOK).errorHandler(ClusterTests.errorHandler(0)));
}
use of org.agrona.BitUtil.SIZE_OF_INT 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);
}
}
Aggregations