use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class RaftBasicTests method testStateMachineMetrics.
public static void testStateMachineMetrics(boolean async, MiniRaftCluster cluster, Logger LOG) throws Exception {
RaftServer.Division leader = waitForLeader(cluster);
try (final RaftClient client = cluster.createClient()) {
Gauge appliedIndexGauge = getStatemachineGaugeWithName(leader, STATEMACHINE_APPLIED_INDEX_GAUGE);
Gauge smAppliedIndexGauge = getStatemachineGaugeWithName(leader, STATEMACHINE_APPLY_COMPLETED_GAUGE);
long appliedIndexBefore = (Long) appliedIndexGauge.getValue();
long smAppliedIndexBefore = (Long) smAppliedIndexGauge.getValue();
checkFollowerCommitLagsLeader(cluster);
if (async) {
CompletableFuture<RaftClientReply> replyFuture = client.async().send(new SimpleMessage("abc"));
replyFuture.get();
} else {
client.io().send(new SimpleMessage("abc"));
}
long appliedIndexAfter = (Long) appliedIndexGauge.getValue();
long smAppliedIndexAfter = (Long) smAppliedIndexGauge.getValue();
checkFollowerCommitLagsLeader(cluster);
Assert.assertTrue("StateMachine Applied Index not incremented", appliedIndexAfter > appliedIndexBefore);
Assert.assertTrue("StateMachine Apply completed Index not incremented", smAppliedIndexAfter > smAppliedIndexBefore);
}
}
use of org.apache.ratis.client.RaftClient in project alluxio by Alluxio.
the class RaftJournalSystem method resetPriorities.
/**
* Resets RaftPeer priorities.
*
* @throws IOException
*/
public synchronized void resetPriorities() throws IOException {
List<RaftPeer> resetPeers = new ArrayList<>();
final int NEUTRAL_PRIORITY = 1;
for (RaftPeer peer : mRaftGroup.getPeers()) {
resetPeers.add(RaftPeer.newBuilder(peer).setPriority(NEUTRAL_PRIORITY).build());
}
LOG.info("Resetting RaftPeer priorities");
try (RaftClient client = createClient()) {
RaftClientReply reply = client.admin().setConfiguration(resetPeers);
processReply(reply, "failed to reset master priorities to 1");
}
}
use of org.apache.ratis.client.RaftClient in project alluxio by Alluxio.
the class RaftJournalSystem method removeQuorumServer.
/**
* Removes from RAFT quorum, a server with given address.
* For server to be removed, it should be in unavailable state in quorum.
*
* @param serverNetAddress address of the server to remove from the quorum
* @throws IOException
*/
public synchronized void removeQuorumServer(NetAddress serverNetAddress) throws IOException {
InetSocketAddress serverAddress = InetSocketAddress.createUnresolved(serverNetAddress.getHost(), serverNetAddress.getRpcPort());
RaftPeerId peerId = RaftJournalUtils.getPeerId(serverAddress);
try (RaftClient client = createClient()) {
Collection<RaftPeer> peers = mServer.getGroups().iterator().next().getPeers();
RaftClientReply reply = client.admin().setConfiguration(peers.stream().filter(peer -> !peer.getId().equals(peerId)).collect(Collectors.toList()));
if (reply.getException() != null) {
throw reply.getException();
}
}
}
use of org.apache.ratis.client.RaftClient in project alluxio by Alluxio.
the class RaftJournalSystem method sendMessageAsync.
/**
* Sends a message to a raft server asynchronously.
*
* @param server the raft peer id of the target server
* @param message the message to send
* @return a future to be completed with the client reply
*/
public synchronized CompletableFuture<RaftClientReply> sendMessageAsync(RaftPeerId server, Message message) {
RaftClient client = createClient();
RaftClientRequest request = RaftClientRequest.newBuilder().setClientId(mRawClientId).setServerId(server).setGroupId(RAFT_GROUP_ID).setCallId(nextCallId()).setMessage(message).setType(RaftClientRequest.staleReadRequestType(0)).setSlidingWindowEntry(null).build();
return client.getClientRpc().sendRequestAsync(request).whenComplete((reply, t) -> {
try {
client.close();
} catch (IOException e) {
throw new CompletionException(e);
}
});
}
use of org.apache.ratis.client.RaftClient in project alluxio by Alluxio.
the class RaftJournalSystem method transferLeadership.
/**
* Transfers the leadership of the quorum to another server.
*
* @param newLeaderNetAddress the address of the server
* @return the guid of transfer leader command
*/
public synchronized String transferLeadership(NetAddress newLeaderNetAddress) {
final boolean allowed = mTransferLeaderAllowed.getAndSet(false);
String transferId = UUID.randomUUID().toString();
if (!allowed) {
String msg = "transfer is not allowed at the moment because the master is " + (mRaftJournalWriter == null ? "still gaining primacy" : "already transferring the ") + "leadership";
mErrorMessages.put(transferId, TransferLeaderMessage.newBuilder().setMsg(msg).build());
return transferId;
}
try {
InetSocketAddress serverAddress = InetSocketAddress.createUnresolved(newLeaderNetAddress.getHost(), newLeaderNetAddress.getRpcPort());
List<RaftPeer> oldPeers = new ArrayList<>(mRaftGroup.getPeers());
// The NetUtil function is used by Ratis to convert InetSocketAddress to string
String strAddr = NetUtils.address2String(serverAddress);
// if you cannot find the address in the quorum, throw exception.
if (oldPeers.stream().map(RaftPeer::getAddress).noneMatch(addr -> addr.equals(strAddr))) {
throw new IOException(String.format("<%s> is not part of the quorum <%s>.", strAddr, oldPeers.stream().map(RaftPeer::getAddress).collect(Collectors.toList())));
}
if (strAddr.equals(mRaftGroup.getPeer(mPeerId).getAddress())) {
throw new IOException(String.format("%s is already the leader", strAddr));
}
RaftPeerId newLeaderPeerId = RaftJournalUtils.getPeerId(serverAddress);
/* update priorities to enable transfer */
List<RaftPeer> peersWithNewPriorities = new ArrayList<>();
for (RaftPeer peer : oldPeers) {
peersWithNewPriorities.add(RaftPeer.newBuilder(peer).setPriority(peer.getId().equals(newLeaderPeerId) ? 2 : 1).build());
}
try (RaftClient client = createClient()) {
String stringPeers = "[" + peersWithNewPriorities.stream().map(RaftPeer::toString).collect(Collectors.joining(", ")) + "]";
LOG.info("Applying new peer state before transferring leadership: {}", stringPeers);
RaftClientReply reply = client.admin().setConfiguration(peersWithNewPriorities);
processReply(reply, "failed to set master priorities before initiating election");
/* transfer leadership */
LOG.info("Transferring leadership to master with address <{}> and with RaftPeerId <{}>", serverAddress, newLeaderPeerId);
// fire and forget: need to immediately return as the master will shut down its RPC servers
// once the TransferLeadershipRequest is initiated.
final int SLEEP_TIME_MS = 3_000;
final int TRANSFER_LEADER_WAIT_MS = 30_000;
new Thread(() -> {
try {
Thread.sleep(SLEEP_TIME_MS);
RaftClientReply reply1 = client.admin().transferLeadership(newLeaderPeerId, TRANSFER_LEADER_WAIT_MS);
processReply(reply1, "election failed");
} catch (Throwable t) {
LOG.error("caught an error when executing transfer: {}", t.getMessage());
// we only allow transfers again if the transfer is unsuccessful: a success means it
// will soon lose primacy
mTransferLeaderAllowed.set(true);
mErrorMessages.put(transferId, TransferLeaderMessage.newBuilder().setMsg(t.getMessage()).build());
/* checking the transfer happens in {@link QuorumElectCommand} */
}
}).start();
LOG.info("Transferring leadership initiated");
}
} catch (Throwable t) {
mTransferLeaderAllowed.set(true);
LOG.warn(t.getMessage());
mErrorMessages.put(transferId, TransferLeaderMessage.newBuilder().setMsg(t.getMessage()).build());
}
return transferId;
}
Aggregations