use of io.dingodb.raft.Status in project dingo by dingodb.
the class ReadOnlyServiceImpl method addRequest.
@Override
public void addRequest(final byte[] reqCtx, final ReadIndexClosure closure) {
if (this.shutdownLatch != null) {
Utils.runClosureInThread(closure, new Status(RaftError.EHOSTDOWN, "Was stopped"));
throw new IllegalStateException("Service already shutdown.");
}
try {
EventTranslator<ReadIndexEvent> translator = (event, sequence) -> {
event.done = closure;
event.requestContext = new Bytes(reqCtx);
event.startTime = Utils.monotonicMs();
};
int retryTimes = 0;
while (true) {
if (this.readIndexQueue.tryPublishEvent(translator)) {
break;
} else {
retryTimes++;
if (retryTimes > MAX_ADD_REQUEST_RETRY_TIMES) {
Utils.runClosureInThread(closure, new Status(RaftError.EBUSY, "Node is busy, has too many read-only requests."));
this.nodeMetrics.recordTimes("read-index-overload-times", 1);
LOG.warn("Node {} ReadOnlyServiceImpl readIndexQueue is overload.", this.node.getNodeId());
return;
}
ThreadHelper.onSpinWait();
}
}
} catch (final Exception e) {
Utils.runClosureInThread(closure, new Status(RaftError.EPERM, "Node is down."));
}
}
use of io.dingodb.raft.Status in project dingo by dingodb.
the class ReadOnlyServiceImpl method join.
@Override
public void join() throws InterruptedException {
if (this.shutdownLatch != null) {
this.shutdownLatch.await();
}
this.readIndexDisruptor.shutdown();
resetPendingStatusError(new Status(RaftError.ESTOP, "Node is quit."));
this.scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS);
}
use of io.dingodb.raft.Status in project dingo by dingodb.
the class Replicator method onHeartbeatReturned.
static void onHeartbeatReturned(final ThreadId id, final Status status, final RpcRequests.AppendEntriesRequest request, final RpcRequests.AppendEntriesResponse response, final long rpcSendTime) {
if (id == null) {
// replicator already was destroyed.
return;
}
final long startTimeMs = Utils.nowMs();
Replicator r;
if ((r = (Replicator) id.lock()) == null) {
return;
}
boolean doUnlock = true;
try {
final boolean isLogDebugEnabled = LOG.isDebugEnabled();
StringBuilder sb = null;
if (isLogDebugEnabled) {
sb = //
new StringBuilder("Node ").append(//
r.options.getGroupId()).append(//
':').append(//
r.options.getServerId()).append(//
" received HeartbeatResponse from ").append(//
r.options.getPeerId()).append(//
" prevLogIndex=").append(//
request.getPrevLogIndex()).append(//
" prevLogTerm=").append(request.getPrevLogTerm());
}
if (!status.isOk()) {
if (isLogDebugEnabled) {
//
sb.append(" fail, sleep, status=").append(status);
LOG.debug(sb.toString());
}
r.setState(State.Probe);
notifyReplicatorStatusListener(r, ReplicatorEvent.ERROR, status);
if (++r.consecutiveErrorTimes % 10 == 0) {
LOG.warn("Fail to issue RPC to {}, consecutiveErrorTimes={}, error={}", r.options.getPeerId(), r.consecutiveErrorTimes, status);
}
r.startHeartbeatTimer(startTimeMs);
return;
}
r.consecutiveErrorTimes = 0;
if (response.getTerm() > r.options.getTerm()) {
if (isLogDebugEnabled) {
//
sb.append(" fail, greater term ").append(//
response.getTerm()).append(//
" expect term ").append(r.options.getTerm());
LOG.debug(sb.toString());
}
final NodeImpl node = r.options.getNode();
r.notifyOnCaughtUp(RaftError.EPERM.getNumber(), true);
r.destroy();
node.increaseTermTo(response.getTerm(), new Status(RaftError.EHIGHERTERMRESPONSE, "Leader receives higher term heartbeat_response from peer:%s", r.options.getPeerId()));
return;
}
if (!response.getSuccess() && response.hasLastLogIndex()) {
if (isLogDebugEnabled) {
//
sb.append(" fail, response term ").append(//
response.getTerm()).append(//
" lastLogIndex ").append(response.getLastLogIndex());
LOG.debug(sb.toString());
}
LOG.warn("Heartbeat to peer {} failure, try to send a probe request.", r.options.getPeerId());
doUnlock = false;
r.sendProbeRequest();
r.startHeartbeatTimer(startTimeMs);
return;
}
if (isLogDebugEnabled) {
LOG.debug(sb.toString());
}
if (rpcSendTime > r.lastRpcSendTimestamp) {
r.lastRpcSendTimestamp = rpcSendTime;
}
r.startHeartbeatTimer(startTimeMs);
} finally {
if (doUnlock) {
id.unlock();
}
}
}
use of io.dingodb.raft.Status in project dingo by dingodb.
the class ResetPeerRequestProcessor method processRequest0.
@Override
protected Message processRequest0(final CliRequestContext ctx, final CliRequests.ResetPeerRequest request, final RpcRequestClosure done) {
final Configuration newConf = new Configuration();
for (final String peerIdStr : request.getNewPeersList()) {
final PeerId peer = new PeerId();
if (peer.parse(peerIdStr)) {
newConf.addPeer(peer);
} else {
return //
RpcFactoryHelper.responseFactory().newResponse(defaultResp(), RaftError.EINVAL, "Fail to parse peer id %s", peerIdStr);
}
}
LOG.info("Receive ResetPeerRequest to {} from {}, new conf is {}", ctx.node.getNodeId(), done.getRpcCtx().getRemoteAddress(), newConf);
final Status st = ctx.node.resetPeers(newConf);
return //
RpcFactoryHelper.responseFactory().newResponse(defaultResp(), st);
}
use of io.dingodb.raft.Status in project dingo by dingodb.
the class Replicator method onTimeoutNowReturned.
@SuppressWarnings("unused")
static void onTimeoutNowReturned(final ThreadId id, final Status status, final RpcRequests.TimeoutNowRequest request, final RpcRequests.TimeoutNowResponse response, final boolean stopAfterFinish) {
final Replicator r = (Replicator) id.lock();
if (r == null) {
return;
}
final boolean isLogDebugEnabled = LOG.isDebugEnabled();
StringBuilder sb = null;
if (isLogDebugEnabled) {
sb = //
new StringBuilder("Node ").append(r.options.getGroupId()).append(":").append(//
r.options.getServerId()).append(//
" received TimeoutNowResponse from ").append(r.options.getPeerId());
}
if (!status.isOk()) {
if (isLogDebugEnabled) {
sb.append(" fail:").append(status);
LOG.debug(sb.toString());
}
notifyReplicatorStatusListener(r, ReplicatorEvent.ERROR, status);
if (stopAfterFinish) {
r.notifyOnCaughtUp(RaftError.ESTOP.getNumber(), true);
r.destroy();
} else {
id.unlock();
}
return;
}
if (isLogDebugEnabled) {
sb.append(response.getSuccess() ? " success" : " fail");
LOG.debug(sb.toString());
}
if (response.getTerm() > r.options.getTerm()) {
final NodeImpl node = r.options.getNode();
r.notifyOnCaughtUp(RaftError.EPERM.getNumber(), true);
r.destroy();
node.increaseTermTo(response.getTerm(), new Status(RaftError.EHIGHERTERMRESPONSE, "Leader receives higher term timeout_now_response from peer:%s", r.options.getPeerId()));
return;
}
if (stopAfterFinish) {
r.notifyOnCaughtUp(RaftError.ESTOP.getNumber(), true);
r.destroy();
} else {
id.unlock();
}
}
Aggregations