use of com.alipay.sofa.jraft.entity.PeerId in project sofa-jraft by sofastack.
the class ConfigurationEntryTest method testIsValid.
@Test
public void testIsValid() {
ConfigurationEntry entry = TestUtils.getConfEntry("localhost:8081,localhost:8082,localhost:8083", null);
assertTrue(entry.isValid());
entry = TestUtils.getConfEntry("localhost:8081,localhost:8082,localhost:8083", "localhost:8081,localhost:8082,localhost:8084");
assertTrue(entry.isValid());
entry.getConf().addLearner(new PeerId("localhost", 8084));
assertFalse(entry.isValid());
entry.getConf().addLearner(new PeerId("localhost", 8081));
assertFalse(entry.isValid());
}
use of com.alipay.sofa.jraft.entity.PeerId in project sofa-jraft by sofastack.
the class AbstractPlacementDriverClient method getLeader.
@Override
public Endpoint getLeader(final long regionId, final boolean forceRefresh, final long timeoutMillis) {
final String raftGroupId = JRaftHelper.getJRaftGroupId(this.clusterName, regionId);
PeerId leader = getLeader(raftGroupId, forceRefresh, timeoutMillis);
if (leader == null && !forceRefresh) {
// Could not found leader from cache, try again and force refresh cache
leader = getLeader(raftGroupId, true, timeoutMillis);
}
if (leader == null) {
throw new RouteTableException("no leader in group: " + raftGroupId);
}
return leader.getEndpoint();
}
use of com.alipay.sofa.jraft.entity.PeerId in project sofa-jraft by sofastack.
the class NodeImpl method handleRequestVoteRequest.
@Override
public Message handleRequestVoteRequest(final RequestVoteRequest request) {
boolean doUnlock = true;
this.writeLock.lock();
try {
if (!this.state.isActive()) {
LOG.warn("Node {} is not in active state, currTerm={}.", getNodeId(), this.currTerm);
return //
RpcFactoryHelper.responseFactory().newResponse(RequestVoteResponse.getDefaultInstance(), RaftError.EINVAL, "Node %s is not in active state, state %s.", getNodeId(), this.state.name());
}
final PeerId candidateId = new PeerId();
if (!candidateId.parse(request.getServerId())) {
LOG.warn("Node {} received RequestVoteRequest from {} serverId bad format.", getNodeId(), request.getServerId());
return //
RpcFactoryHelper.responseFactory().newResponse(RequestVoteResponse.getDefaultInstance(), RaftError.EINVAL, "Parse candidateId failed: %s.", request.getServerId());
}
// noinspection ConstantConditions
do {
// check term
if (request.getTerm() >= this.currTerm) {
LOG.info("Node {} received RequestVoteRequest from {}, term={}, currTerm={}.", getNodeId(), request.getServerId(), request.getTerm(), this.currTerm);
// increase current term, change state to follower
if (request.getTerm() > this.currTerm) {
stepDown(request.getTerm(), false, new Status(RaftError.EHIGHERTERMRESPONSE, "Raft node receives higher term RequestVoteRequest."));
}
} else {
// ignore older term
LOG.info("Node {} ignore RequestVoteRequest from {}, term={}, currTerm={}.", getNodeId(), request.getServerId(), request.getTerm(), this.currTerm);
break;
}
doUnlock = false;
this.writeLock.unlock();
final LogId lastLogId = this.logManager.getLastLogId(true);
doUnlock = true;
this.writeLock.lock();
// vote need ABA check after unlock&writeLock
if (request.getTerm() != this.currTerm) {
LOG.warn("Node {} raise term {} when get lastLogId.", getNodeId(), this.currTerm);
break;
}
final boolean logIsOk = new LogId(request.getLastLogIndex(), request.getLastLogTerm()).compareTo(lastLogId) >= 0;
if (logIsOk && (this.votedId == null || this.votedId.isEmpty())) {
stepDown(request.getTerm(), false, new Status(RaftError.EVOTEFORCANDIDATE, "Raft node votes for some candidate, step down to restart election_timer."));
this.votedId = candidateId.copy();
this.metaStorage.setVotedFor(candidateId);
}
} while (false);
return //
RequestVoteResponse.newBuilder().setTerm(//
this.currTerm).setGranted(//
request.getTerm() == this.currTerm && candidateId.equals(this.votedId)).build();
} finally {
if (doUnlock) {
this.writeLock.unlock();
}
}
}
use of com.alipay.sofa.jraft.entity.PeerId in project sofa-jraft by sofastack.
the class NodeImpl method readLeader.
private void readLeader(final ReadIndexRequest request, final ReadIndexResponse.Builder respBuilder, final RpcResponseClosure<ReadIndexResponse> closure) {
final int quorum = getQuorum();
if (quorum <= 1) {
// Only one peer, fast path.
//
respBuilder.setSuccess(true).setIndex(this.ballotBox.getLastCommittedIndex());
closure.setResponse(respBuilder.build());
closure.run(Status.OK());
return;
}
final long lastCommittedIndex = this.ballotBox.getLastCommittedIndex();
if (this.logManager.getTerm(lastCommittedIndex) != this.currTerm) {
// Reject read only request when this leader has not committed any log entry at its term
closure.run(new Status(RaftError.EAGAIN, "ReadIndex request rejected because leader has not committed any log entry at its term, logIndex=%d, currTerm=%d.", lastCommittedIndex, this.currTerm));
return;
}
respBuilder.setIndex(lastCommittedIndex);
if (request.getPeerId() != null) {
// request from follower or learner, check if the follower/learner is in current conf.
final PeerId peer = new PeerId();
peer.parse(request.getServerId());
if (!this.conf.contains(peer) && !this.conf.containsLearner(peer)) {
closure.run(new Status(RaftError.EPERM, "Peer %s is not in current configuration: %s.", peer, this.conf));
return;
}
}
ReadOnlyOption readOnlyOpt = this.raftOptions.getReadOnlyOptions();
if (readOnlyOpt == ReadOnlyOption.ReadOnlyLeaseBased && !isLeaderLeaseValid()) {
// If leader lease timeout, we must change option to ReadOnlySafe
readOnlyOpt = ReadOnlyOption.ReadOnlySafe;
}
switch(readOnlyOpt) {
case ReadOnlySafe:
final List<PeerId> peers = this.conf.getConf().getPeers();
Requires.requireTrue(peers != null && !peers.isEmpty(), "Empty peers");
final ReadIndexHeartbeatResponseClosure heartbeatDone = new ReadIndexHeartbeatResponseClosure(closure, respBuilder, quorum, peers.size());
// Send heartbeat requests to followers
for (final PeerId peer : peers) {
if (peer.equals(this.serverId)) {
continue;
}
this.replicatorGroup.sendHeartbeat(peer, heartbeatDone);
}
break;
case ReadOnlyLeaseBased:
// Responses to followers and local node.
respBuilder.setSuccess(true);
closure.setResponse(respBuilder.build());
closure.run(Status.OK());
break;
}
}
use of com.alipay.sofa.jraft.entity.PeerId in project sofa-jraft by sofastack.
the class NodeImpl method getAliveNodes.
// in read_lock
private List<PeerId> getAliveNodes(final Collection<PeerId> peers, final long monotonicNowMs) {
final int leaderLeaseTimeoutMs = this.options.getLeaderLeaseTimeoutMs();
final List<PeerId> alivePeers = new ArrayList<>();
for (final PeerId peer : peers) {
if (peer.equals(this.serverId)) {
alivePeers.add(peer.copy());
continue;
}
if (monotonicNowMs - this.replicatorGroup.getLastRpcSendTimestamp(peer) <= leaderLeaseTimeoutMs) {
alivePeers.add(peer.copy());
}
}
return alivePeers;
}
Aggregations