use of io.dingodb.raft.Status in project dingo by dingodb.
the class CliServiceImpl method changePeers.
@Override
public Status changePeers(final String groupId, final Configuration conf, final Configuration newPeers) {
Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");
Requires.requireNonNull(conf, "Null configuration");
Requires.requireNonNull(newPeers, "Null new peers");
final PeerId leaderId = new PeerId();
final Status st = checkLeaderAndConnect(groupId, conf, leaderId);
if (!st.isOk()) {
return st;
}
final CliRequests.ChangePeersRequest.Builder rb = //
CliRequests.ChangePeersRequest.newBuilder().setGroupId(//
groupId).setLeaderId(leaderId.toString());
for (final PeerId peer : newPeers) {
rb.addNewPeers(peer.toString());
}
try {
final Message result = this.cliClientService.changePeers(leaderId.getEndpoint(), rb.build(), null).get();
if (result instanceof CliRequests.ChangePeersResponse) {
final CliRequests.ChangePeersResponse resp = (CliRequests.ChangePeersResponse) result;
recordConfigurationChange(groupId, resp.getOldPeersList(), resp.getNewPeersList());
return Status.OK();
} else {
return statusFromResponse(result);
}
} catch (final Exception e) {
return new Status(-1, e.getMessage());
}
}
use of io.dingodb.raft.Status in project dingo by dingodb.
the class CliServiceImpl method removeLearners.
@Override
public Status removeLearners(final String groupId, final Configuration conf, final List<PeerId> learners) {
checkLearnersOpParams(groupId, conf, learners);
final PeerId leaderId = new PeerId();
final Status st = getLeader(groupId, conf, leaderId);
if (!st.isOk()) {
return st;
}
if (!this.cliClientService.connect(leaderId.getEndpoint())) {
return new Status(-1, "Fail to init channel to leader %s", leaderId);
}
final CliRequests.RemoveLearnersRequest.Builder rb = //
CliRequests.RemoveLearnersRequest.newBuilder().setGroupId(//
groupId).setLeaderId(leaderId.toString());
for (final PeerId peer : learners) {
rb.addLearners(peer.toString());
}
try {
final Message result = this.cliClientService.removeLearners(leaderId.getEndpoint(), rb.build(), null).get();
return processLearnersOpResponse(groupId, result, "removing learners: %s", learners);
} catch (final Exception e) {
return new Status(-1, e.getMessage());
}
}
use of io.dingodb.raft.Status in project dingo by dingodb.
the class NodeImpl method readIndex.
@Override
public void readIndex(final byte[] requestContext, final ReadIndexClosure done) {
if (this.shutdownLatch != null) {
Utils.runClosureInThread(done, new Status(RaftError.ENODESHUTDOWN, "Node is shutting down."));
throw new IllegalStateException("Node is shutting down");
}
Requires.requireNonNull(done, "Null closure");
this.readOnlyService.addRequest(requestContext, done);
}
use of io.dingodb.raft.Status in project dingo by dingodb.
the class NodeImpl method resetPeers.
@Override
public Status resetPeers(final Configuration newPeers) {
Requires.requireNonNull(newPeers, "Null new peers");
Requires.requireTrue(!newPeers.isEmpty(), "Empty new peers");
Requires.requireTrue(newPeers.isValid(), "Invalid new peers: %s", newPeers);
this.writeLock.lock();
try {
if (newPeers.isEmpty()) {
LOG.warn("Node {} set empty peers.", getNodeId());
return new Status(RaftError.EINVAL, "newPeers is empty");
}
if (!this.state.isActive()) {
LOG.warn("Node {} is in state {}, can't set peers.", getNodeId(), this.state);
return new Status(RaftError.EPERM, "Bad state: %s", this.state);
}
// bootstrap?
if (this.conf.getConf().isEmpty()) {
LOG.info("Node {} set peers to {} from empty.", getNodeId(), newPeers);
this.conf.setConf(newPeers);
stepDown(this.currTerm + 1, false, new Status(RaftError.ESETPEER, "Set peer from empty configuration"));
return Status.OK();
}
if (this.state == State.STATE_LEADER && this.confCtx.isBusy()) {
LOG.warn("Node {} set peers need wait current conf changing.", getNodeId());
return new Status(RaftError.EBUSY, "Changing to another configuration");
}
// check equal, maybe retry direct return
if (this.conf.getConf().equals(newPeers)) {
return Status.OK();
}
final Configuration newConf = new Configuration(newPeers);
LOG.info("Node {} set peers from {} to {}.", getNodeId(), this.conf.getConf(), newPeers);
this.conf.setConf(newConf);
this.conf.getOldConf().reset();
stepDown(this.currTerm + 1, false, new Status(RaftError.ESETPEER, "Raft node set peer normally"));
return Status.OK();
} finally {
this.writeLock.unlock();
}
}
use of io.dingodb.raft.Status in project dingo by dingodb.
the class NodeImpl method handleInstallSnapshot.
@Override
public Message handleInstallSnapshot(final RpcRequests.InstallSnapshotRequest request, final RpcRequestClosure done) {
if (this.snapshotExecutor == null) {
return //
RpcFactoryHelper.responseFactory().newResponse(RpcRequests.InstallSnapshotResponse.getDefaultInstance(), RaftError.EINVAL, "Not supported snapshot");
}
final PeerId serverId = new PeerId();
if (!serverId.parse(request.getServerId())) {
LOG.warn("Node {} ignore InstallSnapshotRequest from {} bad server id.", getNodeId(), request.getServerId());
return //
RpcFactoryHelper.responseFactory().newResponse(RpcRequests.InstallSnapshotResponse.getDefaultInstance(), RaftError.EINVAL, "Parse serverId failed: %s", request.getServerId());
}
this.writeLock.lock();
try {
if (!this.state.isActive()) {
LOG.warn("Node {} ignore InstallSnapshotRequest as it is not in active state {}.", getNodeId(), this.state);
return //
RpcFactoryHelper.responseFactory().newResponse(RpcRequests.InstallSnapshotResponse.getDefaultInstance(), RaftError.EINVAL, "Node %s:%s is not in active state, state %s.", this.groupId, this.serverId, this.state.name());
}
if (request.getTerm() < this.currTerm) {
LOG.warn("Node {} ignore stale InstallSnapshotRequest from {}, term={}, currTerm={}.", getNodeId(), request.getPeerId(), request.getTerm(), this.currTerm);
return //
RpcRequests.InstallSnapshotResponse.newBuilder().setTerm(//
this.currTerm).setSuccess(//
false).build();
}
checkStepDown(request.getTerm(), serverId);
if (!serverId.equals(this.leaderId)) {
LOG.error("Another peer {} declares that it is the leader at term {} which was occupied by leader {}.", serverId, this.currTerm, this.leaderId);
// Increase the term by 1 and make both leaders step down to minimize the
// loss of split brain
stepDown(request.getTerm() + 1, false, new Status(RaftError.ELEADERCONFLICT, "More than one leader in the same term."));
return //
RpcRequests.InstallSnapshotResponse.newBuilder().setTerm(//
request.getTerm() + 1).setSuccess(//
false).build();
}
} finally {
this.writeLock.unlock();
}
final long startMs = Utils.monotonicMs();
try {
if (LOG.isInfoEnabled()) {
LOG.info("Node {} received InstallSnapshotRequest from {}, lastIncludedLogIndex={}, lastIncludedLogTerm={}, lastLogId={}.", getNodeId(), request.getServerId(), request.getMeta().getLastIncludedIndex(), request.getMeta().getLastIncludedTerm(), this.logManager.getLastLogId(false));
}
this.snapshotExecutor.installSnapshot(request, RpcRequests.InstallSnapshotResponse.newBuilder(), done);
return null;
} finally {
this.metrics.recordLatency("install-snapshot", Utils.monotonicMs() - startMs);
}
}
Aggregations