use of org.apache.ignite.client.ClientConnectionException in project ignite by apache.
the class ReliableChannel method applyOnDefaultChannel.
/**
* Apply specified {@code function} on any of available channel.
*/
private <T> T applyOnDefaultChannel(Function<ClientChannel, T> function, ClientOperation op, int attemptsLimit, Consumer<Integer> attemptsCallback) {
ClientConnectionException failure = null;
for (int attempt = 0; attempt < attemptsLimit; attempt++) {
ClientChannelHolder hld = null;
ClientChannel c = null;
try {
if (closed)
throw new ClientException("Channel is closed");
curChannelsGuard.readLock().lock();
try {
hld = channels.get(curChIdx);
} finally {
curChannelsGuard.readLock().unlock();
}
c = hld.getOrCreateChannel();
if (c != null) {
attemptsCallback.accept(attempt + 1);
return function.apply(c);
}
} catch (ClientConnectionException e) {
if (failure == null)
failure = e;
else
failure.addSuppressed(e);
onChannelFailure(hld, c);
if (op != null && !shouldRetry(op, attempt, e))
break;
}
}
throw failure;
}
use of org.apache.ignite.client.ClientConnectionException in project ignite by apache.
the class ReliableChannel method handleServiceAsync.
/**
* Handles serviceAsync results and retries as needed.
*/
private <T> void handleServiceAsync(final CompletableFuture<T> fut, ClientOperation op, Consumer<PayloadOutputChannel> payloadWriter, Function<PayloadInputChannel, T> payloadReader, int attemptsLimit, ClientConnectionException failure) {
ClientChannel ch;
// Workaround to store used attempts value within lambda body.
int[] attemptsCnt = new int[1];
try {
ch = applyOnDefaultChannel(channel -> channel, null, attemptsLimit, v -> attemptsCnt[0] = v);
} catch (Throwable ex) {
if (failure != null) {
failure.addSuppressed(ex);
fut.completeExceptionally(failure);
return;
}
fut.completeExceptionally(ex);
return;
}
ch.serviceAsync(op, payloadWriter, payloadReader).handle((res, err) -> {
if (err == null) {
fut.complete(res);
return null;
}
ClientConnectionException failure0 = failure;
if (err instanceof ClientConnectionException) {
try {
// Will try to reinit channels if topology changed.
onChannelFailure(ch);
} catch (Throwable ex) {
fut.completeExceptionally(ex);
return null;
}
if (failure0 == null)
failure0 = (ClientConnectionException) err;
else
failure0.addSuppressed(err);
int attempt = attemptsCnt[0];
int leftAttempts = attemptsLimit - attempt;
// If it is a first retry then reset attempts (as for initialization we use only 1 attempt).
if (failure == null)
leftAttempts = getRetryLimit() - 1;
if (leftAttempts > 0 && shouldRetry(op, attempt, failure0)) {
handleServiceAsync(fut, op, payloadWriter, payloadReader, leftAttempts, failure0);
return null;
}
} else {
fut.completeExceptionally(err instanceof ClientException ? err : new ClientException(err));
return null;
}
fut.completeExceptionally(failure0);
return null;
});
}
use of org.apache.ignite.client.ClientConnectionException in project ignite by apache.
the class TcpClientChannel method addNotificationListener.
/**
* {@inheritDoc}
*/
@Override
public void addNotificationListener(ClientNotificationType type, Long rsrcId, NotificationListener lsnr) {
Queue<T2<ByteBuffer, Exception>> pendingQueue = null;
notificationLsnrsGuard.writeLock().lock();
try {
if (closed())
throw new ClientConnectionException("Channel is closed");
Map<Long, NotificationListener> lsnrs = notificationLsnrs[type.ordinal()];
if (lsnrs == null)
notificationLsnrs[type.ordinal()] = lsnrs = new ConcurrentHashMap<>();
lsnrs.put(rsrcId, lsnr);
if (type.keepNotificationsWithoutListener())
pendingQueue = pendingNotifications[type.ordinal()].remove(rsrcId);
} finally {
notificationLsnrsGuard.writeLock().unlock();
}
// Drain pending notifications queue.
if (pendingQueue != null)
pendingQueue.forEach(n -> lsnr.acceptNotification(n.get1(), n.get2()));
}
use of org.apache.ignite.client.ClientConnectionException in project ignite by apache.
the class TcpClientChannel method processNextMessage.
/**
* Process next message from the input stream and complete corresponding future.
*/
private void processNextMessage(ByteBuffer buf) throws ClientProtocolError, ClientConnectionException {
BinaryInputStream dataInput = BinaryByteBufferInputStream.create(buf);
if (protocolCtx == null) {
// Process handshake.
pendingReqs.remove(-1L).onDone(buf);
return;
}
Long resId = dataInput.readLong();
int status = 0;
ClientOperation notificationOp = null;
if (protocolCtx.isFeatureSupported(PARTITION_AWARENESS)) {
short flags = dataInput.readShort();
if ((flags & ClientFlag.AFFINITY_TOPOLOGY_CHANGED) != 0) {
long topVer = dataInput.readLong();
int minorTopVer = dataInput.readInt();
srvTopVer = new AffinityTopologyVersion(topVer, minorTopVer);
for (Consumer<ClientChannel> lsnr : topChangeLsnrs) lsnr.accept(this);
}
if ((flags & ClientFlag.NOTIFICATION) != 0) {
short notificationCode = dataInput.readShort();
notificationOp = ClientOperation.fromCode(notificationCode);
if (notificationOp == null || notificationOp.notificationType() == null)
throw new ClientProtocolError(String.format("Unexpected notification code [%d]", notificationCode));
}
if ((flags & ClientFlag.ERROR) != 0)
status = dataInput.readInt();
} else
status = dataInput.readInt();
int hdrSize = dataInput.position();
int msgSize = buf.limit();
ByteBuffer res;
Exception err;
if (status == 0) {
err = null;
res = msgSize > hdrSize ? buf : null;
} else if (status == ClientStatus.SECURITY_VIOLATION) {
err = new ClientAuthorizationException();
res = null;
} else {
String errMsg = ClientUtils.createBinaryReader(null, dataInput).readString();
err = new ClientServerError(errMsg, status, resId);
res = null;
}
if (notificationOp == null) {
// Respone received.
ClientRequestFuture pendingReq = pendingReqs.remove(resId);
if (pendingReq == null)
throw new ClientProtocolError(String.format("Unexpected response ID [%s]", resId));
pendingReq.onDone(res, err);
} else {
// Notification received.
ClientNotificationType notificationType = notificationOp.notificationType();
asyncContinuationExecutor.execute(() -> {
NotificationListener lsnr = null;
notificationLsnrsGuard.readLock().lock();
try {
Map<Long, NotificationListener> lsrns = notificationLsnrs[notificationType.ordinal()];
if (lsrns != null)
lsnr = lsrns.get(resId);
if (notificationType.keepNotificationsWithoutListener() && lsnr == null) {
pendingNotifications[notificationType.ordinal()].computeIfAbsent(resId, k -> new ConcurrentLinkedQueue<>()).add(new T2<>(res, err));
}
} finally {
notificationLsnrsGuard.readLock().unlock();
}
if (lsnr != null)
lsnr.acceptNotification(res, err);
});
}
}
use of org.apache.ignite.client.ClientConnectionException in project ignite by apache.
the class TcpClientChannel method handshake.
/**
* Client handshake.
*/
private void handshake(ProtocolVersion ver, String user, String pwd, Map<String, String> userAttrs) throws ClientConnectionException, ClientAuthenticationException, ClientProtocolError {
ClientRequestFuture fut = new ClientRequestFuture();
pendingReqs.put(-1L, fut);
handshakeReq(ver, user, pwd, userAttrs);
try {
ByteBuffer res = timeout > 0 ? fut.get(timeout) : fut.get();
handshakeRes(res, ver, user, pwd, userAttrs);
} catch (IgniteCheckedException e) {
throw new ClientConnectionException(e.getMessage(), e);
}
}
Aggregations