use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class TestRestartRaftPeer method restartFollower.
@Test
public void restartFollower() throws Exception {
cluster.start();
RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = cluster.getLeader().getId();
final RaftClient client = cluster.createClient(leaderId);
// write some messages
final byte[] content = new byte[1024];
Arrays.fill(content, (byte) 1);
final SimpleMessage message = new SimpleMessage(new String(content));
for (int i = 0; i < 10; i++) {
Assert.assertTrue(client.send(message).isSuccess());
}
// restart a follower
RaftPeerId followerId = cluster.getFollowers().get(0).getId();
LOG.info("Restart follower {}", followerId);
cluster.restartServer(followerId, false);
// write some more messages
for (int i = 0; i < 10; i++) {
Assert.assertTrue(client.send(message).isSuccess());
}
client.close();
// make sure the restarted follower can catchup
boolean catchup = false;
long lastAppliedIndex = 0;
for (int i = 0; i < 10 && !catchup; i++) {
Thread.sleep(500);
lastAppliedIndex = cluster.getServer(followerId).getImpl().getState().getLastAppliedIndex();
catchup = lastAppliedIndex >= 20;
}
Assert.assertTrue("lastAppliedIndex=" + lastAppliedIndex, catchup);
// make sure the restarted peer's log segments is correct
cluster.restartServer(followerId, false);
Assert.assertTrue(cluster.getServer(followerId).getImpl().getState().getLog().getLastEntryTermIndex().getIndex() >= 20);
}
use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class TestRaftServerWithGrpc method testServerRestartOnException.
@Test
public void testServerRestartOnException() throws Exception {
RaftProperties properties = new RaftProperties();
final MiniRaftClusterWithGRpc cluster = MiniRaftClusterWithGRpc.FACTORY.newCluster(1, properties);
cluster.start();
RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
GrpcConfigKeys.Server.setPort(properties, cluster.getLeader().getServerRpc().getInetSocketAddress().getPort());
// Create a raft server proxy with server rpc bound to a different address
// compared to leader. This helps in locking the raft storage directory to
// be used by next raft server proxy instance.
RaftServerTestUtil.getRaftServerProxy(leaderId, cluster.getLeader().getStateMachine(), cluster.getGroup(), new RaftProperties(), null);
// Close the server rpc for leader so that new raft server can be bound to it.
cluster.getLeader().getServerRpc().close();
try {
// Create a raft server proxy with server rpc bound to same address as
// the leader. This step would fail as the raft storage has been locked by
// the raft server proxy created earlier. Raft server proxy should close
// the rpc server on failure.
RaftServerTestUtil.getRaftServerProxy(leaderId, cluster.getLeader().getStateMachine(), cluster.getGroup(), properties, null);
} catch (Exception e) {
}
// Try to start a raft server rpc at the leader address.
cluster.getServer(leaderId).getFactory().newRaftServerRpc(cluster.getServer(leaderId));
}
use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class ReinitializationBaseTest method runTestReinitializeMultiGroups.
public static <T extends Throwable> void runTestReinitializeMultiGroups(MiniRaftCluster cluster, int[] idIndex, int chosen, CheckedBiConsumer<MiniRaftCluster, RaftGroup, T> checker) throws IOException, InterruptedException, T {
if (chosen < 0) {
chosen = ThreadLocalRandom.current().nextInt(idIndex.length);
}
final String type = cluster.getClass().getSimpleName() + Arrays.toString(idIndex) + "chosen=" + chosen;
LOG.info("\n\nrunTestReinitializeMultiGroups with " + type + ": " + cluster.printServers());
// Start server with an empty conf
final RaftGroup emptyGroup = new RaftGroup(RaftGroupId.randomId());
final List<RaftPeerId> ids = Arrays.stream(MiniRaftCluster.generateIds(idIndex[idIndex.length - 1], 0)).map(RaftPeerId::valueOf).collect(Collectors.toList());
ids.forEach(id -> cluster.putNewServer(id, emptyGroup, true));
LOG.info("putNewServer: " + cluster.printServers());
cluster.start();
LOG.info("start: " + cluster.printServers());
// Make sure that there are no leaders.
TimeUnit.SECONDS.sleep(1);
Assert.assertNull(cluster.getLeader());
// Reinitialize servers to three groups
final List<RaftPeer> allPeers = cluster.getPeers();
Collections.sort(allPeers, Comparator.comparing(p -> p.getId().toString()));
final RaftGroup[] groups = new RaftGroup[idIndex.length];
for (int i = 0; i < idIndex.length; i++) {
final RaftGroupId gid = RaftGroupId.randomId();
final int previous = i == 0 ? 0 : idIndex[i - 1];
final RaftPeer[] peers = allPeers.subList(previous, idIndex[i]).toArray(RaftPeer.emptyArray());
groups[i] = new RaftGroup(gid, peers);
LOG.info(i + ") starting " + groups[i]);
for (RaftPeer p : peers) {
try (final RaftClient client = cluster.createClient(p.getId(), emptyGroup)) {
client.reinitialize(groups[i], p.getId());
}
}
Assert.assertNotNull(RaftTestUtil.waitForLeader(cluster, true, gid));
checker.accept(cluster, groups[i]);
}
printThreadCount(type, "start groups");
LOG.info("start groups: " + cluster.printServers());
// randomly close two of the groups (i.e. reinitialize to empty peers)
LOG.info("chosen = " + chosen + ", " + groups[chosen]);
for (int i = 0; i < groups.length; i++) {
if (i != chosen) {
final RaftGroup g = groups[i];
final RaftGroup newGroup = new RaftGroup(g.getGroupId());
LOG.info(i + ") close " + cluster.printServers(g.getGroupId()));
for (RaftPeer p : g.getPeers()) {
try (final RaftClient client = cluster.createClient(p.getId(), g)) {
client.reinitialize(newGroup, p.getId());
}
}
}
}
printThreadCount(type, "close groups");
LOG.info("close groups: " + cluster.printServers());
// update chosen group to use all the peers
final RaftGroup newGroup = new RaftGroup(groups[chosen].getGroupId());
for (int i = 0; i < groups.length; i++) {
if (i != chosen) {
LOG.info(i + ") reinitialize: " + cluster.printServers(groups[i].getGroupId()));
for (RaftPeer p : groups[i].getPeers()) {
try (final RaftClient client = cluster.createClient(p.getId(), groups[i])) {
client.reinitialize(newGroup, p.getId());
}
}
}
}
LOG.info(chosen + ") setConfiguration: " + cluster.printServers(groups[chosen].getGroupId()));
try (final RaftClient client = cluster.createClient(groups[chosen])) {
client.setConfiguration(allPeers.toArray(RaftPeer.emptyArray()));
}
Assert.assertNotNull(RaftTestUtil.waitForLeader(cluster, true));
checker.accept(cluster, groups[chosen]);
LOG.info("update groups: " + cluster.printServers());
printThreadCount(type, "update groups");
cluster.shutdown();
printThreadCount(type, "shutdown");
}
use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class ReinitializationBaseTest method testReinitialize.
@Test
public void testReinitialize() throws Exception {
final MiniRaftCluster cluster = getCluster(0);
LOG.info("Start testReinitialize" + cluster.printServers());
// Start server with an empty conf
final RaftGroupId groupId = RaftGroupId.randomId();
final RaftGroup group = new RaftGroup(groupId);
final List<RaftPeerId> ids = Arrays.stream(MiniRaftCluster.generateIds(3, 0)).map(RaftPeerId::valueOf).collect(Collectors.toList());
ids.forEach(id -> cluster.putNewServer(id, group, true));
LOG.info("putNewServer: " + cluster.printServers());
cluster.start();
LOG.info("start: " + cluster.printServers());
// Make sure that there are no leaders.
TimeUnit.SECONDS.sleep(1);
Assert.assertNull(cluster.getLeader());
// Reinitialize servers
final RaftGroup newGroup = new RaftGroup(groupId, cluster.getPeers());
final RaftClient client = cluster.createClient(newGroup);
for (RaftPeer p : newGroup.getPeers()) {
client.reinitialize(newGroup, p.getId());
}
Assert.assertNotNull(RaftTestUtil.waitForLeader(cluster, true));
cluster.shutdown();
}
use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.
the class OrderedAsync method sendRequest.
private CompletableFuture<RaftClientReply> sendRequest(PendingOrderedRequest pending) {
final RetryPolicy retryPolicy = client.getRetryPolicy();
final CompletableFuture<RaftClientReply> f;
final RaftClientRequest request;
if (getSlidingWindow((RaftPeerId) null).isFirst(pending.getSeqNum())) {
pending.setFirstRequest();
}
request = pending.newRequest();
LOG.debug("{}: send* {}", client.getId(), request);
f = client.getClientRpc().sendRequestAsync(request);
return f.thenApply(reply -> {
LOG.debug("{}: receive* {}", client.getId(), reply);
getSlidingWindow(request).receiveReply(request.getSlidingWindowEntry().getSeqNum(), reply, this::sendRequestWithRetry);
return reply;
}).exceptionally(e -> {
if (LOG.isTraceEnabled()) {
LOG.trace(client.getId() + ": Failed* " + request, e);
} else {
LOG.debug("{}: Failed* {} with {}", client.getId(), request, e);
}
e = JavaUtils.unwrapCompletionException(e);
if (e instanceof IOException && !(e instanceof GroupMismatchException)) {
pending.incrementExceptionCount(e);
final ClientRetryEvent event = new ClientRetryEvent(request, e, pending);
if (!retryPolicy.handleAttemptFailure(event).shouldRetry()) {
handleAsyncRetryFailure(event);
} else {
if (e instanceof NotLeaderException) {
NotLeaderException nle = (NotLeaderException) e;
client.handleNotLeaderException(request, nle, this::resetSlidingWindow);
} else {
client.handleIOException(request, (IOException) e, null, this::resetSlidingWindow);
}
}
throw new CompletionException(e);
}
failAllAsyncRequests(request, e);
return null;
});
}
Aggregations