use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class LogAppenderTests method testFollowerHeartbeatMetric.
@Test
public void testFollowerHeartbeatMetric() throws IOException, InterruptedException {
// Start a 3 node Ratis ring.
final MiniRaftCluster cluster = newCluster(3);
cluster.start();
final RaftServer.Division leaderServer = waitForLeader(cluster);
// Write 10 messages to leader.
try (RaftClient client = cluster.createClient(leaderServer.getId())) {
for (int i = 1; i <= 10; i++) {
client.io().send(new RaftTestUtil.SimpleMessage("Msg to make leader ready " + i));
}
} catch (IOException e) {
throw e;
}
final RatisMetricRegistry ratisMetricRegistry = ((RaftServerMetricsImpl) leaderServer.getRaftServerMetrics()).getRegistry();
// Get all last_heartbeat_elapsed_time metric gauges. Should be equal to number of followers.
SortedMap<String, Gauge> heartbeatElapsedTimeGauges = ratisMetricRegistry.getGauges((s, metric) -> s.contains("lastHeartbeatElapsedTime"));
assertTrue(heartbeatElapsedTimeGauges.size() == 2);
for (RaftServer.Division followerServer : cluster.getFollowers()) {
String followerId = followerServer.getId().toString();
Gauge metric = heartbeatElapsedTimeGauges.entrySet().parallelStream().filter(e -> e.getKey().contains(followerId)).iterator().next().getValue();
// Metric for this follower exists.
assertTrue(metric != null);
// Metric in nanos > 0.
assertTrue((long) metric.getValue() > 0);
// Try to get Heartbeat metrics for follower.
final RaftServerMetricsImpl followerMetrics = (RaftServerMetricsImpl) followerServer.getRaftServerMetrics();
// Metric should not exist. It only exists in leader.
assertTrue(followerMetrics.getRegistry().getGauges((s, m) -> s.contains("lastHeartbeatElapsedTime")).isEmpty());
for (boolean heartbeat : new boolean[] { true, false }) {
assertTrue(followerMetrics.getFollowerAppendEntryTimer(heartbeat).getMeanRate() > 0.0d);
assertTrue(followerMetrics.getFollowerAppendEntryTimer(heartbeat).getCount() > 0L);
}
}
}
use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class LogAppenderTests method runTest.
void runTest(CLUSTER cluster) throws Exception {
final int numMsgs = 10;
final int numClients = 5;
final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
List<RaftClient> clients = new ArrayList<>();
try {
List<Sender> senders = new ArrayList<>();
// start several clients and write concurrently
final CountDownLatch latch = new CountDownLatch(1);
for (int i = 0; i < numClients; i++) {
RaftClient client = cluster.createClient(leaderId);
clients.add(client);
senders.add(new Sender(client, numMsgs, latch));
}
senders.forEach(Thread::start);
latch.countDown();
for (Sender s : senders) {
s.join();
final Exception e = s.exception.get();
if (e != null) {
throw e;
}
Assert.assertTrue(s.succeed.get());
}
} finally {
for (int i = 0; i < clients.size(); i++) {
try {
clients.get(i).close();
} catch (Exception ignored) {
LOG.warn("{} is ignored", JavaUtils.getClassSimpleName(ignored.getClass()), ignored);
}
}
}
final RaftServer.Division leader = cluster.getLeader();
final RaftLog leaderLog = cluster.getLeader().getRaftLog();
final EnumMap<LogEntryBodyCase, AtomicLong> counts = RaftTestUtil.countEntries(leaderLog);
LOG.info("counts = " + counts);
Assert.assertEquals(6 * numMsgs * numClients, counts.get(LogEntryBodyCase.STATEMACHINELOGENTRY).get());
final LogEntryProto last = RaftTestUtil.getLastEntry(LogEntryBodyCase.STATEMACHINELOGENTRY, leaderLog);
LOG.info("last = {}", LogProtoUtils.toLogEntryString(last));
Assert.assertNotNull(last);
Assert.assertTrue(last.getIndex() <= leader.getInfo().getLastAppliedIndex());
}
use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class RaftBasicTests method testRequestTimeout.
public static void testRequestTimeout(boolean async, MiniRaftCluster cluster, Logger LOG) throws Exception {
waitForLeader(cluster);
final Timestamp startTime = Timestamp.currentTime();
try (final RaftClient client = cluster.createClient()) {
// Get the next callId to be used by the client
final ClientInvocationId invocationId = RaftClientTestUtil.getClientInvocationId(client);
// Create an entry corresponding to the callId and clientId
// in each server's retry cache.
cluster.getServerAliveStream().forEach(raftServer -> RetryCacheTestUtil.getOrCreateEntry(raftServer, invocationId));
// The retry is successful when the retry cache entry for the corresponding callId and clientId expires.
if (async) {
CompletableFuture<RaftClientReply> replyFuture = client.async().send(new SimpleMessage("abc"));
replyFuture.get();
} else {
client.io().send(new SimpleMessage("abc"));
}
// Eventually the request would be accepted by the server
// when the retry cache entry is invalidated.
// The duration for which the client waits should be more than the retryCacheExpiryDuration.
final TimeDuration duration = startTime.elapsedTime();
TimeDuration retryCacheExpiryDuration = RaftServerConfigKeys.RetryCache.expiryTime(cluster.getProperties());
Assert.assertTrue(duration.compareTo(retryCacheExpiryDuration) >= 0);
}
}
use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class RetryCacheTests method runTestRetryOnNewLeader.
void runTestRetryOnNewLeader(CLUSTER cluster) throws Exception {
RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = cluster.getLeaderAndSendFirstMessage(false).getId();
try (final RaftClient client = cluster.createClient(leaderId)) {
RaftClientRpc rpc = client.getClientRpc();
final long callId = 999;
RaftClientRequest r = cluster.newRaftClientRequest(client.getId(), leaderId, callId, new SimpleMessage("message"));
assertReply(rpc.sendRequest(r), client, callId);
final long oldLastApplied = cluster.getLeader().getInfo().getLastAppliedIndex();
// trigger the reconfiguration, make sure the original leader is kicked out
PeerChanges change = cluster.addNewPeers(2, true);
RaftPeer[] allPeers = cluster.removePeers(2, true, asList(change.newPeers)).allPeersInNewConf;
// trigger setConfiguration
cluster.setConfiguration(allPeers);
final RaftPeerId newLeaderId = JavaUtils.attemptRepeatedly(() -> {
final RaftPeerId id = RaftTestUtil.waitForLeader(cluster).getId();
Assert.assertNotEquals(leaderId, id);
return id;
}, 10, TimeDuration.valueOf(100, TimeUnit.MILLISECONDS), "wait for a leader different than " + leaderId, LOG);
Assert.assertNotEquals(leaderId, newLeaderId);
// same clientId and callId in the request
r = cluster.newRaftClientRequest(client.getId(), newLeaderId, callId, new SimpleMessage("message"));
rpc.addRaftPeers(Arrays.asList(change.newPeers));
for (int i = 0; i < 10; i++) {
try {
assertReply(rpc.sendRequest(r), client, callId);
LOG.info("successfully sent out the retry request_" + i);
} catch (Exception e) {
LOG.info("hit exception while retrying the same request: " + r, e);
}
Thread.sleep(100);
}
// check the new leader and make sure the retry did not get committed
Assert.assertEquals(0, count(cluster.getLeader().getRaftLog(), oldLastApplied + 1));
}
}
use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class WatchRequestTests method runSingleTest.
static void runSingleTest(CheckedConsumer<TestParameters, Exception> testCase, MiniRaftCluster cluster, Logger LOG) throws Exception {
try (final RaftClient client = cluster.createClient(RaftTestUtil.waitForLeader(cluster).getId())) {
final int[] numMessages = { 1 };
for (int n : numMessages) {
final TestParameters p = new TestParameters(n, client, cluster, LOG);
LOG.info("{}) {}, {}", n, p, cluster.printServers());
testCase.accept(p);
}
}
}
Aggregations