use of org.apache.ratis.statemachine.SimpleStateMachine4Testing in project incubator-ratis by apache.
the class RaftAsyncExceptionTests method runTestTimeoutException.
private void runTestTimeoutException(CLUSTER cluster) throws Exception {
// send a message to make sure the cluster is working
try (RaftClient client = cluster.createClient()) {
final RaftClientReply reply = client.io().send(new SimpleMessage("m0"));
Assert.assertTrue(reply.isSuccess());
RaftClientConfigKeys.Rpc.setRequestTimeout(properties.get(), ONE_SECOND);
// Block StartTransaction
StreamSupport.stream(cluster.getServers().spliterator(), false).map(cluster::getDivision).map(SimpleStateMachine4Testing::get).forEach(SimpleStateMachine4Testing::blockStartTransaction);
final CompletableFuture<RaftClientReply> replyFuture = client.async().send(new SimpleMessage("m1"));
FIVE_SECONDS.sleep();
// Unblock StartTransaction
StreamSupport.stream(cluster.getServers().spliterator(), false).map(cluster::getDivision).map(SimpleStateMachine4Testing::get).forEach(SimpleStateMachine4Testing::unblockStartTransaction);
// The request should succeed after start transaction is unblocked
Assert.assertTrue(replyFuture.get(FIVE_SECONDS.getDuration(), FIVE_SECONDS.getUnit()).isSuccess());
}
}
use of org.apache.ratis.statemachine.SimpleStateMachine4Testing in project incubator-ratis by apache.
the class RaftAsyncTests method testAsyncRequestSemaphore.
@Test
public void testAsyncRequestSemaphore() throws InterruptedException, IOException {
LOG.info("Running testAsyncRequestSemaphore");
CLUSTER cluster = getFactory().newCluster(NUM_SERVERS, properties);
Assert.assertNull(cluster.getLeader());
cluster.start();
waitForLeader(cluster);
int numMessages = RaftClientConfigKeys.Async.maxOutstandingRequests(properties);
CompletableFuture[] futures = new CompletableFuture[numMessages + 1];
final RaftTestUtil.SimpleMessage[] messages = RaftTestUtil.SimpleMessage.create(numMessages);
final RaftClient client = cluster.createClient();
// Set blockTransaction flag so that transaction blocks
for (RaftServerProxy server : cluster.getServers()) {
((SimpleStateMachine4Testing) server.getStateMachine()).setBlockTransaction(true);
}
// Send numMessages which are blocked and do not release the client semaphore permits
AtomicInteger blockedRequestsCount = new AtomicInteger();
for (int i = 0; i < numMessages; i++) {
blockedRequestsCount.getAndIncrement();
futures[i] = client.sendAsync(messages[i]);
blockedRequestsCount.decrementAndGet();
}
Assert.assertTrue(blockedRequestsCount.get() == 0);
ExecutorService threadPool = Executors.newFixedThreadPool(1);
futures[numMessages] = CompletableFuture.supplyAsync(() -> {
blockedRequestsCount.incrementAndGet();
client.sendAsync(new RaftTestUtil.SimpleMessage("n1"));
blockedRequestsCount.decrementAndGet();
return null;
}, threadPool);
// Allow the last msg to be sent
while (blockedRequestsCount.get() != 1) {
Thread.sleep(1000);
}
Assert.assertTrue(blockedRequestsCount.get() == 1);
// Since all semaphore permits are acquired the last message sent is in queue
RaftClientTestUtil.assertAsyncRequestSemaphore(client, 0, 1);
// Unset the blockTransaction flag so that semaphore permits can be released
for (RaftServerProxy server : cluster.getServers()) {
((SimpleStateMachine4Testing) server.getStateMachine()).setBlockTransaction(false);
}
for (int i = 0; i <= numMessages; i++) {
futures[i].join();
}
Assert.assertTrue(blockedRequestsCount.get() == 0);
cluster.shutdown();
}
use of org.apache.ratis.statemachine.SimpleStateMachine4Testing in project incubator-ratis by apache.
the class TestSegmentedRaftLog method testSegmentedRaftLogStateMachineData.
@Test
public void testSegmentedRaftLogStateMachineData() throws Exception {
final SegmentRange range = new SegmentRange(0, 10, 1, true);
final List<LogEntryProto> entries = prepareLogEntries(range, null, true, new ArrayList<>());
final SimpleStateMachine4Testing sm = new SimpleStateMachine4Testing();
try (SegmentedRaftLog raftLog = new SegmentedRaftLog(memberId, null, sm, null, null, storage, () -> -1, properties)) {
raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
int next = 0;
long flush = -1;
assertIndices(raftLog, flush, next);
raftLog.appendEntry(entries.get(next++));
assertIndices(raftLog, flush, next);
raftLog.appendEntry(entries.get(next++));
assertIndices(raftLog, flush, next);
raftLog.appendEntry(entries.get(next++));
assertIndicesMultipleAttempts(raftLog, flush += 3, next);
sm.blockFlushStateMachineData();
raftLog.appendEntry(entries.get(next++));
sm.blockWriteStateMachineData();
final Thread t = startAppendEntryThread(raftLog, entries.get(next++));
TimeUnit.SECONDS.sleep(1);
assertTrue(t.isAlive());
sm.unblockWriteStateMachineData();
assertIndices(raftLog, flush, next);
TimeUnit.SECONDS.sleep(1);
assertIndices(raftLog, flush, next);
sm.unblockFlushStateMachineData();
assertIndicesMultipleAttempts(raftLog, flush + 2, next);
// raftLog.appendEntry(entry).get() won't return
// until sm.unblockFlushStateMachineData() was called.
t.join();
}
}
use of org.apache.ratis.statemachine.SimpleStateMachine4Testing in project incubator-ratis by apache.
the class TestRaftServerWithGrpc method testRequestMetrics.
void testRequestMetrics(MiniRaftClusterWithGrpc cluster) throws Exception {
try (RaftClient client = cluster.createClient()) {
// send a request to make sure leader is ready
final CompletableFuture<RaftClientReply> f = client.async().send(new SimpleMessage("testing"));
Assert.assertTrue(f.get().isSuccess());
}
SimpleStateMachine4Testing stateMachine = SimpleStateMachine4Testing.get(cluster.getLeader());
stateMachine.blockFlushStateMachineData();
// Block stateMachine flush data, so that 2nd request will not be
// completed, and so it will not be removed from pending request map.
List<RaftClient> clients = new ArrayList<>();
try {
RaftClient client = cluster.createClient(cluster.getLeader().getId(), RetryPolicies.noRetry());
clients.add(client);
client.async().send(new SimpleMessage("2nd Message"));
final SortedMap<String, Gauge> gaugeMap = getRaftServerMetrics(cluster.getLeader()).getRegistry().getGauges((s, metric) -> s.contains(REQUEST_MEGA_BYTE_SIZE));
for (int i = 0; i < 10; i++) {
client = cluster.createClient(cluster.getLeader().getId(), RetryPolicies.noRetry());
clients.add(client);
client.async().send(new SimpleMessage("message " + i));
}
// Because we have passed 11 requests, and the element queue size is 10.
RaftTestUtil.waitFor(() -> getRaftServerMetrics(cluster.getLeader()).getCounter(REQUEST_QUEUE_LIMIT_HIT_COUNTER).getCount() == 1, 300, 5000);
stateMachine.unblockFlushStateMachineData();
// Send a message with 1025kb , our byte size limit is 1024kb (1mb) , so it should fail
// and byte size counter limit will be hit.
client = cluster.createClient(cluster.getLeader().getId(), RetryPolicies.noRetry());
final SizeInBytes size = SizeInBytes.valueOf("1025kb");
final ByteString bytes = randomByteString(size.getSizeInt());
Assert.assertEquals(size.getSizeInt(), bytes.size());
client.async().send(new SimpleMessage(size + "-message", bytes));
clients.add(client);
RaftTestUtil.waitFor(() -> getRaftServerMetrics(cluster.getLeader()).getCounter(REQUEST_BYTE_SIZE_LIMIT_HIT_COUNTER).getCount() == 1, 300, 5000);
Assert.assertEquals(2, getRaftServerMetrics(cluster.getLeader()).getCounter(RESOURCE_LIMIT_HIT_COUNTER).getCount());
} finally {
for (RaftClient client : clients) {
client.close();
}
}
}
use of org.apache.ratis.statemachine.SimpleStateMachine4Testing in project incubator-ratis by apache.
the class TestRaftWithGrpc method runTestUpdateViaHeartbeat.
void runTestUpdateViaHeartbeat(MiniRaftClusterWithGrpc cluster) throws Exception {
waitForLeader(cluster);
try (final RaftClient client = cluster.createClient()) {
// block append requests
cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).map(SimpleStateMachine4Testing::get).forEach(SimpleStateMachine4Testing::blockWriteStateMachineData);
CompletableFuture<RaftClientReply> replyFuture = client.async().send(new RaftTestUtil.SimpleMessage("abc"));
TimeDuration.valueOf(5, TimeUnit.SECONDS).sleep();
// replyFuture should not be completed until append request is unblocked.
Assert.assertFalse(replyFuture.isDone());
// unblock append request.
cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).map(SimpleStateMachine4Testing::get).forEach(SimpleStateMachine4Testing::unblockWriteStateMachineData);
final RaftLog leaderLog = cluster.getLeader().getRaftLog();
// The entries have been appended in the followers
// although the append entry timed out at the leader
cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).forEach(raftServer -> JavaUtils.runAsUnchecked(() -> JavaUtils.attempt(() -> {
final long leaderNextIndex = leaderLog.getNextIndex();
final LogEntryHeader[] leaderEntries = leaderLog.getEntries(0, Long.MAX_VALUE);
final RaftLog followerLog = raftServer.getRaftLog();
Assert.assertEquals(leaderNextIndex, followerLog.getNextIndex());
final LogEntryHeader[] serverEntries = followerLog.getEntries(0, Long.MAX_VALUE);
Assert.assertArrayEquals(serverEntries, leaderEntries);
}, 10, HUNDRED_MILLIS, "assertRaftLog-" + raftServer.getId(), LOG)));
// Wait for heartbeats from leader to be received by followers
Thread.sleep(500);
RaftServerTestUtil.getLogAppenders(cluster.getLeader()).forEach(logAppender -> JavaUtils.runAsUnchecked(() -> JavaUtils.attempt(() -> {
final long leaderNextIndex = leaderLog.getNextIndex();
// FollowerInfo in the leader state should have updated next and match index.
final long followerMatchIndex = logAppender.getFollower().getMatchIndex();
Assert.assertTrue(followerMatchIndex >= leaderNextIndex - 1);
Assert.assertEquals(followerMatchIndex + 1, logAppender.getFollower().getNextIndex());
}, 10, HUNDRED_MILLIS, "assertRaftLog-" + logAppender.getFollower(), LOG)));
}
}
Aggregations