use of org.apache.ignite.raft.jraft.rpc.Message in project ignite-3 by apache.
the class AbstractClientService method invokeWithDone.
public <T extends Message> CompletableFuture<Message> invokeWithDone(final Endpoint endpoint, final Message request, final InvokeContext ctx, final RpcResponseClosure<T> done, final int timeoutMs, final Executor rpcExecutor) {
final RpcClient rc = this.rpcClient;
final FutureImpl<Message> future = new FutureImpl<>();
final Executor currExecutor = rpcExecutor != null ? rpcExecutor : this.rpcExecutor;
try {
if (rc == null) {
// TODO asch replace with ignite exception, check all places IGNITE-14832
future.completeExceptionally(new IllegalStateException("Client service is uninitialized."));
// should be in another thread to avoid dead locking.
Utils.runClosureInExecutor(currExecutor, done, new Status(RaftError.EINTERNAL, "Client service is uninitialized."));
return future;
}
return rc.invokeAsync(endpoint, request, ctx, new InvokeCallback() {
@Override
public void complete(final Object result, final Throwable err) {
if (err == null) {
Status status = Status.OK();
Message msg;
if (result instanceof ErrorResponse) {
status = handleErrorResponse((ErrorResponse) result);
msg = (Message) result;
} else {
msg = (Message) result;
}
if (done != null) {
try {
if (status.isOk()) {
done.setResponse((T) msg);
}
done.run(status);
} catch (final Throwable t) {
LOG.error("Fail to run RpcResponseClosure, the request is {}.", t, request);
}
}
if (!future.isDone()) {
future.complete(msg);
}
} else {
if (ThrowUtil.hasCause(err, null, ConnectException.class))
// Force logical reconnect.
readyAddresses.remove(endpoint.toString());
if (done != null) {
try {
done.run(new Status(err instanceof InvokeTimeoutException ? RaftError.ETIMEDOUT : RaftError.EINTERNAL, "RPC exception:" + err.getMessage()));
} catch (final Throwable t) {
LOG.error("Fail to run RpcResponseClosure, the request is {}.", t, request);
}
}
if (!future.isDone()) {
future.completeExceptionally(err);
}
}
}
@Override
public Executor executor() {
return currExecutor;
}
}, timeoutMs <= 0 ? this.rpcOptions.getRpcDefaultTimeout() : timeoutMs);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
future.completeExceptionally(e);
// should be in another thread to avoid dead locking.
Utils.runClosureInExecutor(currExecutor, done, new Status(RaftError.EINTR, "Sending rpc was interrupted"));
} catch (final RemotingException e) {
future.completeExceptionally(e);
// should be in another thread to avoid dead locking.
Utils.runClosureInExecutor(currExecutor, done, new Status(RaftError.EINTERNAL, "Fail to send a RPC request:" + e.getMessage()));
}
return future;
}
use of org.apache.ignite.raft.jraft.rpc.Message in project ignite-3 by apache.
the class ReplicatorTest method testOnRpcReturnedMoreLogs.
@Test
public void testOnRpcReturnedMoreLogs() {
final Replicator r = getReplicator();
assertEquals(11, r.getRealNextIndex());
final RpcRequests.AppendEntriesRequest request = createEmptyEntriesRequest();
final RpcRequests.AppendEntriesResponse response = raftOptions.getRaftMessagesFactory().appendEntriesResponse().success(false).lastLogIndex(12).term(1).build();
this.id.unlock();
final Future<Message> rpcInFly = r.getRpcInFly();
assertNotNull(rpcInFly);
Mockito.when(this.logManager.getTerm(9)).thenReturn(1L);
final RpcRequests.AppendEntriesRequest newReq = raftOptions.getRaftMessagesFactory().appendEntriesRequest().groupId("test").serverId(new PeerId("localhost", 8082).toString()).peerId(this.peerId.toString()).term(1).prevLogIndex(9).data(ByteString.EMPTY).prevLogTerm(1).committedIndex(0).build();
Mockito.when(this.rpcService.appendEntries(eq(this.peerId.getEndpoint()), eq(newReq), eq(-1), Mockito.any())).thenReturn(new CompletableFuture<>());
Replicator.onRpcReturned(this.id, Replicator.RequestType.AppendEntries, Status.OK(), request, response, 0, 0, Utils.monotonicMs());
assertNotNull(r.getRpcInFly());
assertNotSame(r.getRpcInFly(), rpcInFly);
assertEquals(Replicator.RunningState.APPENDING_ENTRIES, r.statInfo.runningState);
this.id.unlock();
assertEquals(0, Replicator.getNextIndex(this.id));
assertEquals(10, r.getRealNextIndex());
}
use of org.apache.ignite.raft.jraft.rpc.Message in project ignite-3 by apache.
the class CliServiceImpl method addPeer.
@Override
public Status addPeer(final String groupId, final Configuration conf, final PeerId peer) {
Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");
Requires.requireNonNull(conf, "Null configuration");
Requires.requireNonNull(peer, "Null peer");
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);
}
AddPeerRequest req = cliOptions.getRaftMessagesFactory().addPeerRequest().groupId(groupId).leaderId(leaderId.toString()).peerId(peer.toString()).build();
try {
final Message result = this.cliClientService.addPeer(leaderId.getEndpoint(), req, null).get();
if (result instanceof AddPeerResponse) {
final AddPeerResponse resp = (AddPeerResponse) result;
final Configuration oldConf = new Configuration();
for (final String peerIdStr : resp.oldPeersList()) {
final PeerId oldPeer = new PeerId();
oldPeer.parse(peerIdStr);
oldConf.addPeer(oldPeer);
}
final Configuration newConf = new Configuration();
for (final String peerIdStr : resp.newPeersList()) {
final PeerId newPeer = new PeerId();
newPeer.parse(peerIdStr);
newConf.addPeer(newPeer);
}
LOG.info("Configuration of replication group {} changed from {} to {}.", groupId, oldConf, newConf);
return Status.OK();
} else {
return statusFromResponse(result);
}
} catch (final Exception e) {
return new Status(-1, e.getMessage());
}
}
use of org.apache.ignite.raft.jraft.rpc.Message in project ignite-3 by apache.
the class CliServiceImpl method changePeers.
// TODO refactor addPeer/removePeer/changePeers/transferLeader, remove duplicated code IGNITE-14832
@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 = 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);
}
ChangePeersRequest req = cliOptions.getRaftMessagesFactory().changePeersRequest().groupId(groupId).leaderId(leaderId.toString()).newPeersList(newPeers.getPeers().stream().map(Object::toString).collect(toList())).build();
try {
final Message result = this.cliClientService.changePeers(leaderId.getEndpoint(), req, null).get();
if (result instanceof ChangePeersResponse) {
final ChangePeersResponse resp = (ChangePeersResponse) result;
final Configuration oldConf = new Configuration();
for (final String peerIdStr : resp.oldPeersList()) {
final PeerId oldPeer = new PeerId();
oldPeer.parse(peerIdStr);
oldConf.addPeer(oldPeer);
}
final Configuration newConf = new Configuration();
for (final String peerIdStr : resp.newPeersList()) {
final PeerId newPeer = new PeerId();
newPeer.parse(peerIdStr);
newConf.addPeer(newPeer);
}
LOG.info("Configuration of replication group {} changed from {} to {}", groupId, oldConf, newConf);
return Status.OK();
} else {
return statusFromResponse(result);
}
} catch (final Exception e) {
return new Status(-1, e.getMessage());
}
}
use of org.apache.ignite.raft.jraft.rpc.Message in project ignite-3 by apache.
the class CliServiceImpl method resetPeer.
@Override
public Status resetPeer(final String groupId, final PeerId peerId, final Configuration newPeers) {
Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");
Requires.requireNonNull(peerId, "Null peerId");
Requires.requireNonNull(newPeers, "Null new peers");
if (!this.cliClientService.connect(peerId.getEndpoint())) {
return new Status(-1, "Fail to init channel to %s", peerId);
}
ResetPeerRequest req = cliOptions.getRaftMessagesFactory().resetPeerRequest().groupId(groupId).peerId(peerId.toString()).newPeersList(newPeers.getPeers().stream().map(Object::toString).collect(toList())).build();
try {
final Message result = this.cliClientService.resetPeer(peerId.getEndpoint(), req, null).get();
return statusFromResponse(result);
} catch (final Exception e) {
return new Status(-1, e.getMessage());
}
}
Aggregations