use of io.dingodb.raft.entity.PeerId in project dingo by dingodb.
the class CoordinatorServer method start.
public void start(final CoordinatorOptions opts) throws Exception {
this.svrOpts = opts;
log.info("Coordinator all configuration: {}.", this.svrOpts);
log.info("instance configuration: {}.", DingoOptions.instance());
this.context = new CoordinatorContext();
final String raftId = svrOpts.getRaft().getGroup();
final Endpoint endpoint = new Endpoint(svrOpts.getIp(), svrOpts.getRaft().getPort());
final RocksRawKVStore rawKVStore = createRocksDB();
final CoordinatorStateMachine stateMachine = createStateMachine(raftId, rawKVStore, context);
final Node node = RaftServiceFactory.createRaftNode(raftId, new PeerId(endpoint, 0));
final AsyncKeyValueStore keyValueStore = createStore(rawKVStore, node);
final ScheduleMetaAdaptor scheduleMetaAdaptor = createScheduleMetaAdaptor(keyValueStore);
final TableMetaAdaptor tableMetaAdaptor = createTableMetaAdaptor(keyValueStore, scheduleMetaAdaptor);
final CoordinatorMetaService metaService = createMetaService();
final RowStoreMetaAdaptor rowStoreMetaAdaptor = createRowStoreMetaAdaptor(scheduleMetaAdaptor);
context.coordOpts(svrOpts).endpoint(endpoint).netService(createNetService()).rocksKVStore(rawKVStore).stateMachine(stateMachine).keyValueStore(keyValueStore).node(node).scheduleMetaAdaptor(scheduleMetaAdaptor).serviceProvider(createServiceProvider()).tableMetaAdaptor(tableMetaAdaptor).rowStoreMetaAdaptor(rowStoreMetaAdaptor).metaService(metaService);
NodeManager.getInstance().addAddress(endpoint);
stateMachine.init();
final NodeOptions nodeOptions = initNodeOptions(stateMachine);
node.init(nodeOptions);
keyValueStore.init();
}
use of io.dingodb.raft.entity.PeerId in project dingo by dingodb.
the class RouteTable method refreshLeader.
/**
* Blocking the thread until query_leader finishes.
*
* @param groupId raft group id
* @param timeoutMs timeout millis
* @return operation status
*/
public Status refreshLeader(final CliClientService cliClientService, final String groupId, final int timeoutMs) throws InterruptedException, TimeoutException {
Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");
Requires.requireTrue(timeoutMs > 0, "Invalid timeout: " + timeoutMs);
final Configuration conf = getConfiguration(groupId);
if (conf == null) {
return new Status(RaftError.ENOENT, "Group %s is not registered in RouteTable, forgot to call updateConfiguration?", groupId);
}
final Status st = Status.OK();
final CliRequests.GetLeaderRequest.Builder rb = CliRequests.GetLeaderRequest.newBuilder();
rb.setGroupId(groupId);
final CliRequests.GetLeaderRequest request = rb.build();
TimeoutException timeoutException = null;
for (final PeerId peer : conf) {
if (!cliClientService.connect(peer.getEndpoint())) {
if (st.isOk()) {
st.setError(-1, "Fail to init channel to %s", peer);
} else {
final String savedMsg = st.getErrorMsg();
st.setError(-1, "%s, Fail to init channel to %s", savedMsg, peer);
}
continue;
}
final Future<Message> result = cliClientService.getLeader(peer.getEndpoint(), request, null);
try {
final Message msg = result.get(timeoutMs, TimeUnit.MILLISECONDS);
if (msg instanceof RpcRequests.ErrorResponse) {
if (st.isOk()) {
st.setError(-1, ((RpcRequests.ErrorResponse) msg).getErrorMsg());
} else {
final String savedMsg = st.getErrorMsg();
st.setError(-1, "%s, %s", savedMsg, ((RpcRequests.ErrorResponse) msg).getErrorMsg());
}
} else {
final CliRequests.GetLeaderResponse response = (CliRequests.GetLeaderResponse) msg;
updateLeader(groupId, response.getLeaderId());
return Status.OK();
}
} catch (final TimeoutException e) {
timeoutException = e;
} catch (final ExecutionException e) {
if (st.isOk()) {
st.setError(-1, e.getMessage());
} else {
final String savedMsg = st.getErrorMsg();
st.setError(-1, "%s, %s", savedMsg, e.getMessage());
}
}
}
if (timeoutException != null) {
throw timeoutException;
}
return st;
}
use of io.dingodb.raft.entity.PeerId in project dingo by dingodb.
the class RouteTable method updateLeader.
/**
* Update leader info.
*
* @param groupId raft group id
* @param leaderStr peer string of leader
* @return true on success
*/
public boolean updateLeader(final String groupId, final String leaderStr) {
Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");
Requires.requireTrue(!StringUtils.isBlank(leaderStr), "Blank leader");
final PeerId leader = new PeerId();
if (leader.parse(leaderStr)) {
return updateLeader(groupId, leader);
} else {
LOG.error("Fail to parse leaderStr: {}", leaderStr);
return false;
}
}
use of io.dingodb.raft.entity.PeerId in project dingo by dingodb.
the class RouteTable method refreshConfiguration.
public Status refreshConfiguration(final CliClientService cliClientService, final String groupId, final int timeoutMs) throws InterruptedException, TimeoutException {
Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");
Requires.requireTrue(timeoutMs > 0, "Invalid timeout: " + timeoutMs);
final Configuration conf = getConfiguration(groupId);
if (conf == null) {
return new Status(RaftError.ENOENT, "Group %s is not registered in RouteTable, forgot to call updateConfiguration?", groupId);
}
final Status st = Status.OK();
PeerId leaderId = selectLeader(groupId);
if (leaderId == null) {
refreshLeader(cliClientService, groupId, timeoutMs);
leaderId = selectLeader(groupId);
}
if (leaderId == null) {
st.setError(-1, "Fail to get leader of group %s", groupId);
return st;
}
if (!cliClientService.connect(leaderId.getEndpoint())) {
st.setError(-1, "Fail to init channel to %s", leaderId);
return st;
}
final CliRequests.GetPeersRequest.Builder rb = CliRequests.GetPeersRequest.newBuilder();
rb.setGroupId(groupId);
rb.setLeaderId(leaderId.toString());
try {
final Message result = cliClientService.getPeers(leaderId.getEndpoint(), rb.build(), null).get(timeoutMs, TimeUnit.MILLISECONDS);
if (result instanceof CliRequests.GetPeersResponse) {
final CliRequests.GetPeersResponse resp = (CliRequests.GetPeersResponse) result;
final Configuration newConf = new Configuration();
for (final String peerIdStr : resp.getPeersList()) {
final PeerId newPeer = new PeerId();
newPeer.parse(peerIdStr);
newConf.addPeer(newPeer);
}
if (!conf.equals(newConf)) {
LOG.info("Configuration of replication group {} changed from {} to {}", groupId, conf, newConf);
}
updateConfiguration(groupId, newConf);
} else {
final RpcRequests.ErrorResponse resp = (RpcRequests.ErrorResponse) result;
st.setError(resp.getErrorCode(), resp.getErrorMsg());
}
} catch (final Exception e) {
st.setError(-1, e.getMessage());
}
return st;
}
use of io.dingodb.raft.entity.PeerId in project dingo by dingodb.
the class NodeImpl method bootstrap.
public boolean bootstrap(final BootstrapOptions opts) throws InterruptedException {
if (opts.getLastLogIndex() > 0 && (opts.getGroupConf().isEmpty() || opts.getFsm() == null)) {
LOG.error("Invalid arguments for bootstrap, groupConf={}, fsm={}, lastLogIndex={}.", opts.getGroupConf(), opts.getFsm(), opts.getLastLogIndex());
return false;
}
if (opts.getGroupConf().isEmpty()) {
LOG.error("Bootstrapping an empty node makes no sense.");
return false;
}
Requires.requireNonNull(opts.getServiceFactory(), "Null jraft service factory");
this.serviceFactory = opts.getServiceFactory();
// Term is not an option since changing it is very dangerous
final long bootstrapLogTerm = opts.getLastLogIndex() > 0 ? 1 : 0;
final LogId bootstrapId = new LogId(opts.getLastLogIndex(), bootstrapLogTerm);
this.options = new NodeOptions();
this.raftOptions = this.options.getRaftOptions();
this.metrics = new NodeMetrics(opts.isEnableMetrics());
this.options.setFsm(opts.getFsm());
this.options.setLogUri(opts.getLogUri());
this.options.setRaftMetaUri(opts.getRaftMetaUri());
this.options.setSnapshotUri(opts.getSnapshotUri());
this.configManager = new ConfigurationManager();
// Create fsmCaller at first as logManager needs it to report error
this.fsmCaller = new FSMCallerImpl();
if (!initLogStorage()) {
LOG.error("Fail to init log storage.");
return false;
}
if (!initMetaStorage()) {
LOG.error("Fail to init meta storage.");
return false;
}
if (this.currTerm == 0) {
this.currTerm = 1;
if (!this.metaStorage.setTermAndVotedFor(1, new PeerId())) {
LOG.error("Fail to set term.");
return false;
}
}
if (opts.getFsm() != null && !initFSMCaller(bootstrapId)) {
LOG.error("Fail to init fsm caller.");
return false;
}
final LogEntry entry = new LogEntry(EnumOutter.EntryType.ENTRY_TYPE_CONFIGURATION);
entry.getId().setTerm(this.currTerm);
entry.setPeers(opts.getGroupConf().listPeers());
entry.setLearners(opts.getGroupConf().listLearners());
final List<LogEntry> entries = new ArrayList<>();
entries.add(entry);
final BootstrapStableClosure bootstrapDone = new BootstrapStableClosure();
this.logManager.appendEntries(entries, bootstrapDone);
if (!bootstrapDone.await().isOk()) {
LOG.error("Fail to append configuration.");
return false;
}
if (opts.getLastLogIndex() > 0) {
if (!initSnapshotStorage()) {
LOG.error("Fail to init snapshot storage.");
return false;
}
final SynchronizedClosure snapshotDone = new SynchronizedClosure();
this.snapshotExecutor.doSnapshot(snapshotDone);
if (!snapshotDone.await().isOk()) {
LOG.error("Fail to save snapshot, status={}.", snapshotDone.getStatus());
return false;
}
}
if (this.logManager.getFirstLogIndex() != opts.getLastLogIndex() + 1) {
throw new IllegalStateException("First and last log index mismatch");
}
if (opts.getLastLogIndex() > 0) {
if (this.logManager.getLastLogIndex() != opts.getLastLogIndex()) {
throw new IllegalStateException("Last log index mismatch");
}
} else {
if (this.logManager.getLastLogIndex() != opts.getLastLogIndex() + 1) {
throw new IllegalStateException("Last log index mismatch");
}
}
return true;
}
Aggregations