use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class RaftReconfigurationBaseTest method checkPriority.
private void checkPriority(CLUSTER cluster, RaftGroupId groupId, List<RaftPeer> peersWithPriority) throws InterruptedException {
RaftTestUtil.waitForLeader(cluster, groupId);
for (int i = 0; i < peersWithPriority.size(); i++) {
RaftPeerId peerId = peersWithPriority.get(i).getId();
final RaftServer.Division server = cluster.getDivision(peerId, groupId);
final RaftConfiguration conf = server.getRaftConf();
for (int j = 0; j < peersWithPriority.size(); j++) {
int priorityInConf = conf.getPeer(peersWithPriority.get(j).getId()).getPriority();
Assert.assertEquals(priorityInConf, peersWithPriority.get(j).getPriority());
}
}
}
use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class RaftReconfigurationBaseTest method testLeaderNotReadyException.
/**
* Delay the commit of the leader placeholder log entry and see if the client
* can correctly receive and handle the LeaderNotReadyException.
*/
@Test
public void testLeaderNotReadyException() throws Exception {
LOG.info("Start testLeaderNotReadyException");
final MiniRaftCluster cluster = newCluster(1).initServers();
try {
// delay 1s for each logSync call
cluster.getServers().forEach(peer -> leaderPlaceHolderDelay.setDelayMs(peer.getId().toString(), 2000));
cluster.start();
AtomicBoolean caughtNotReady = new AtomicBoolean(false);
AtomicBoolean success = new AtomicBoolean(false);
final RaftPeerId leaderId = cluster.getPeers().iterator().next().getId();
new Thread(() -> {
try (final RaftClient client = cluster.createClient(leaderId)) {
final RaftClientRpc sender = client.getClientRpc();
final RaftClientRequest request = cluster.newRaftClientRequest(client.getId(), leaderId, new SimpleMessage("test"));
while (!success.get()) {
try {
final RaftClientReply reply = sender.sendRequest(request);
success.set(reply.isSuccess());
if (reply.getException() != null && reply.getException() instanceof LeaderNotReadyException) {
caughtNotReady.set(true);
}
} catch (IOException e) {
LOG.info("Hit other IOException", e);
}
if (!success.get()) {
try {
Thread.sleep(200);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
}
}
} catch (Exception ignored) {
LOG.warn("{} is ignored", JavaUtils.getClassSimpleName(ignored.getClass()), ignored);
}
}).start();
RaftTestUtil.waitForLeader(cluster);
for (int i = 0; !success.get() && i < 5; i++) {
Thread.sleep(1000);
}
Assert.assertTrue(success.get());
Assert.assertTrue(caughtNotReady.get());
} finally {
leaderPlaceHolderDelay.clear();
cluster.shutdown();
}
}
use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class RaftReconfigurationBaseTest method runTestBootstrapReconf.
void runTestBootstrapReconf(int numNewPeer, boolean startNewPeer, CLUSTER cluster) throws Exception {
LOG.info("Originally {} peer(s), add {} more, startNewPeer={}", cluster.getNumServers(), numNewPeer, startNewPeer);
RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = cluster.getLeader().getId();
try (final RaftClient client = cluster.createClient(leaderId)) {
// submit some msgs before reconf
for (int i = 0; i < STAGING_CATCHUP_GAP * 2; i++) {
RaftClientReply reply = client.io().send(new SimpleMessage("m" + i));
Assert.assertTrue(reply.isSuccess());
}
final PeerChanges c1 = cluster.addNewPeers(numNewPeer, startNewPeer);
LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
final AtomicReference<Boolean> success = new AtomicReference<>();
Thread clientThread = new Thread(() -> {
try {
RaftClientReply reply = client.admin().setConfiguration(c1.allPeersInNewConf);
success.set(reply.isSuccess());
} catch (IOException ioe) {
LOG.error("FAILED", ioe);
}
});
clientThread.start();
if (!startNewPeer) {
// Make sure that set configuration is run inside the thread
RaftTestUtil.waitFor(() -> clientThread.isAlive(), 300, 5000);
ONE_SECOND.sleep();
LOG.info("start new peer(s): {}", c1.newPeers);
for (RaftPeer p : c1.newPeers) {
cluster.restartServer(p.getId(), true);
}
}
RaftTestUtil.waitFor(() -> success.get() != null && success.get(), 300, 15000);
LOG.info(cluster.printServers());
final RaftLog leaderLog = cluster.getLeader().getRaftLog();
for (RaftPeer newPeer : c1.newPeers) {
final RaftServer.Division d = cluster.getDivision(newPeer.getId());
RaftTestUtil.waitFor(() -> leaderLog.getEntries(0, Long.MAX_VALUE).length == d.getRaftLog().getEntries(0, Long.MAX_VALUE).length, 300, 15000);
Assert.assertArrayEquals(leaderLog.getEntries(0, Long.MAX_VALUE), d.getRaftLog().getEntries(0, Long.MAX_VALUE));
}
}
}
use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class RaftReconfigurationBaseTest method runTestReconfTwice.
void runTestReconfTwice(CLUSTER cluster) throws Exception {
final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
try (final RaftClient client = cluster.createClient(leaderId)) {
// submit some msgs before reconf
for (int i = 0; i < STAGING_CATCHUP_GAP * 2; i++) {
RaftClientReply reply = client.io().send(new SimpleMessage("m" + i));
Assert.assertTrue(reply.isSuccess());
}
final AtomicBoolean reconf1 = new AtomicBoolean(false);
final AtomicBoolean reconf2 = new AtomicBoolean(false);
final AtomicReference<RaftPeer[]> finalPeers = new AtomicReference<>(null);
final AtomicReference<RaftPeer[]> deadPeers = new AtomicReference<>(null);
CountDownLatch latch = new CountDownLatch(1);
Thread clientThread = new Thread(() -> {
try {
PeerChanges c1 = cluster.addNewPeers(2, true);
LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
RaftClientReply reply = client.admin().setConfiguration(c1.allPeersInNewConf);
reconf1.set(reply.isSuccess());
PeerChanges c2 = cluster.removePeers(2, true, asList(c1.newPeers));
finalPeers.set(c2.allPeersInNewConf);
deadPeers.set(c2.removedPeers);
LOG.info("Start changing the configuration again: {}", asList(c2.allPeersInNewConf));
reply = client.admin().setConfiguration(c2.allPeersInNewConf);
reconf2.set(reply.isSuccess());
latch.countDown();
} catch (Exception ignored) {
LOG.warn("{} is ignored", JavaUtils.getClassSimpleName(ignored.getClass()), ignored);
}
});
clientThread.start();
latch.await();
Assert.assertTrue(reconf1.get());
Assert.assertTrue(reconf2.get());
waitAndCheckNewConf(cluster, finalPeers.get(), 2, null);
final RaftPeerId leader2 = RaftTestUtil.waitForLeader(cluster).getId();
// check configuration manager's internal state
// each reconf will generate two configurations: (old, new) and (new)
cluster.getServerAliveStream().forEach(server -> {
final ConfigurationManager confManager = RaftServerTestUtil.getConfigurationManager(server);
// each reconf will generate two configurations: (old, new) and (new)
// each leader change generates one configuration.
// expectedConf = 1 (init) + 2*2 (two conf changes) + #leader
final int expectedConf = leader2.equals(leaderId) ? 6 : 7;
Assert.assertEquals(server.getId() + ": " + confManager, expectedConf, confManager.numOfConf());
});
}
}
use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class RaftAsyncTests method runTestRequestAsyncWithRetryFailure.
void runTestRequestAsyncWithRetryFailure(boolean initialMessages, CLUSTER cluster) throws Exception {
final TimeDuration sleepTime = HUNDRED_MILLIS;
final RetryLimited retryPolicy = RetryPolicies.retryUpToMaximumCountWithFixedSleep(10, sleepTime);
try (final RaftClient client = cluster.createClient(null, retryPolicy)) {
RaftPeerId leader = null;
if (initialMessages) {
// cluster is already started, send a few success messages
leader = RaftTestUtil.waitForLeader(cluster).getId();
final SimpleMessage[] messages = SimpleMessage.create(10, "initial-");
final List<CompletableFuture<RaftClientReply>> replies = new ArrayList<>();
for (int i = 0; i < messages.length; i++) {
replies.add(client.async().send(messages[i]));
}
for (int i = 0; i < messages.length; i++) {
RaftTestUtil.assertSuccessReply(replies.get(i));
}
// kill the only server
cluster.killServer(leader);
}
// now, either the cluster is not yet started or the server is killed.
final List<CompletableFuture<RaftClientReply>> replies = new ArrayList<>();
{
final SimpleMessage[] messages = SimpleMessage.create(10);
int i = 0;
// send half of the calls without starting the cluster
for (; i < messages.length / 2; i++) {
replies.add(client.async().send(messages[i]));
}
// sleep most of the retry time
sleepTime.apply(t -> t * (retryPolicy.getMaxAttempts() - 1)).sleep();
// send another half of the calls without starting the cluster
for (; i < messages.length; i++) {
replies.add(client.async().send(messages[i]));
}
Assert.assertEquals(messages.length, replies.size());
}
// sleep again so that the first half calls will fail retries.
// the second half still have retry time remaining.
sleepTime.apply(t -> t * 2).sleep();
if (leader != null) {
cluster.restartServer(leader, false);
} else {
cluster.start();
}
// all the calls should fail for ordering guarantee
for (int i = 0; i < replies.size(); i++) {
final CheckedRunnable<Exception> getReply = replies.get(i)::get;
final String name = "retry-failure-" + i;
if (i == 0) {
final Throwable t = testFailureCase(name, getReply, ExecutionException.class, RaftRetryFailureException.class);
assertRaftRetryFailureException((RaftRetryFailureException) t.getCause(), retryPolicy, name);
} else {
testFailureCase(name, getReply, ExecutionException.class, AlreadyClosedException.class, RaftRetryFailureException.class);
}
}
testFailureCaseAsync("last-request", () -> client.async().send(new SimpleMessage("last")), AlreadyClosedException.class, RaftRetryFailureException.class);
}
}
Aggregations