/** * Recursively connects to the partition. */ private void connect(int attempt, CompletableFuture<SessionClient> future) { if (attempt > MAX_ATTEMPTS) { future.completeExceptionally(new PrimitiveException.Unavailable()); return; } primaryElection.getTerm().whenCompleteAsync((term, error) -> { if (error == null) { if (term.primary() == null) { future.completeExceptionally(new PrimitiveException.Unavailable()); } else { this.term = term; protocol.registerEventListener(sessionId, this::handleEvent, threadContext); future.complete(this); } } else { Throwable cause = Throwables.getRootCause(error); if (cause instanceof PrimitiveException.Unavailable || cause instanceof TimeoutException) { threadContext.schedule(Duration.ofMillis(RETRY_DELAY), () -> connect(attempt + 1, future)); } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } } }, threadContext); }
/** * Returns the current primary term. * * @return the current primary term */ private CompletableFuture<PrimaryTerm> term() { CompletableFuture<PrimaryTerm> future = new CompletableFuture<>(); threadContext.execute(() -> { if (term != null) { future.complete(term); } else { primaryElection.getTerm().whenCompleteAsync((term, error) -> { if (term != null) { this.term = term; future.complete(term); } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } }); } }); return future; }
/** * Registers the consumer with the given leader. * * @param leader the leader with which to register the consumer */ private CompletableFuture<Void> register(MemberId leader) { CompletableFuture<Void> future = new CompletableFuture<>(); this.leader = leader; protocol.consume(leader, ConsumeRequest.request(memberId, subject, index + 1)) .whenCompleteAsync((response, error) -> { if (error == null) { if (response.status() == LogResponse.Status.OK) { future.complete(null); } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } } else { future.completeExceptionally(error); } }, threadContext); return future; }
private <T, U> CompletableFuture<U> send(String subject, T request, MemberId memberId) { CompletableFuture<U> future = new CompletableFuture<>(); clusterCommunicator.<T, U>send(subject, request, serializer::encode, serializer::decode, memberId).whenComplete((result, error) -> { if (error == null) { future.complete(result); } else { Throwable cause = Throwables.getRootCause(error); if (cause instanceof MessagingException.NoRemoteHandler) { future.completeExceptionally(new PrimitiveException.Unavailable()); } else { future.completeExceptionally(error); } } }); return future; }
@Override public CompletableFuture<Long> append(byte[] value) { CompletableFuture<Long> future = new CompletableFuture<>(); term().thenCompose(term -> protocol.append(term.primary().memberId(), AppendRequest.request(value))) .whenCompleteAsync((response, error) -> { if (error == null) { if (response.status() == LogResponse.Status.OK) { future.complete(response.index()); } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } } else { future.completeExceptionally(error); } }, threadContext); return future; } }
private void onStateChange(PrimitiveState state) { if (state != PrimitiveState.CONNECTED) { for (LockAttempt attempt : attempts.values()) { getProxyClient().acceptBy(name(), service -> service.unlock(attempt.id())); attempt.completeExceptionally(new PrimitiveException.Unavailable()); } } }
private void execute(PrimitiveOperation operation, int attempt, ComposableFuture<byte[]> future) { if (attempt > MAX_ATTEMPTS) { future.completeExceptionally(new PrimitiveException.Unavailable()); return; threadContext.schedule(Duration.ofMillis(RETRY_DELAY), () -> execute(operation, attempt + 1, future)); } else { future.completeExceptionally(new PrimitiveException.Unavailable());
/** * Returns the current primary term. * * @return the current primary term */ private CompletableFuture<PrimaryTerm> term() { CompletableFuture<PrimaryTerm> future = new CompletableFuture<>(); threadContext.execute(() -> { if (term != null) { future.complete(term); } else { primaryElection.getTerm().whenCompleteAsync((term, error) -> { if (term != null) { this.term = term; future.complete(term); } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } }); } }); return future; }
/** * Registers the consumer with the given leader. * * @param leader the leader with which to register the consumer */ private CompletableFuture<Void> register(MemberId leader) { CompletableFuture<Void> future = new CompletableFuture<>(); this.leader = leader; protocol.consume(leader, ConsumeRequest.request(memberId, subject, index + 1)) .whenCompleteAsync((response, error) -> { if (error == null) { if (response.status() == LogResponse.Status.OK) { future.complete(null); } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } } else { future.completeExceptionally(error); } }, threadContext); return future; }
@Override public CompletableFuture<byte[]> execute(PrimitiveOperation operation) { ComposableFuture<byte[]> future = new ComposableFuture<>(); threadContext.execute(() -> { if (term.primary() == null) { primaryElection.getTerm().whenCompleteAsync((term, error) -> { if (error == null) { if (term.term() <= this.term.term() || term.primary() == null) { future.completeExceptionally(new PrimitiveException.Unavailable()); } else { this.term = term; execute(operation, 1, future); } } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } }, threadContext); } else { execute(operation, 1, future); } }); return future; }
private <T, U> CompletableFuture<U> sendAndReceive(String subject, T request, MemberId memberId) { CompletableFuture<U> future = new CompletableFuture<>(); clusterCommunicator.<T, U>send(subject, request, serializer::encode, serializer::decode, memberId).whenComplete((result, error) -> { if (error == null) { future.complete(result); } else { Throwable cause = Throwables.getRootCause(error); if (cause instanceof MessagingException.NoRemoteHandler) { future.completeExceptionally(new PrimitiveException.Unavailable()); } else { future.completeExceptionally(error); } } }); return future; }
@Override public CompletableFuture<Long> append(byte[] value) { CompletableFuture<Long> future = new CompletableFuture<>(); term().thenCompose(term -> protocol.append(term.primary().memberId(), AppendRequest.request(value))) .whenCompleteAsync((response, error) -> { if (error == null) { if (response.status() == LogResponse.Status.OK) { future.complete(response.index()); } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } } else { future.completeExceptionally(error); } }, threadContext); return future; } }
private <T, U> CompletableFuture<U> send(String subject, T request, MemberId memberId) { CompletableFuture<U> future = new CompletableFuture<>(); clusterCommunicator.<T, U>send(subject, request, serializer::encode, serializer::decode, memberId).whenComplete((result, error) -> { if (error == null) { future.complete(result); } else { Throwable cause = Throwables.getRootCause(error); if (cause instanceof MessagingException.NoRemoteHandler) { future.completeExceptionally(new PrimitiveException.Unavailable()); } else { future.completeExceptionally(error); } } }); return future; }
@Override PrimitiveException createException(String message) { return message != null ? new PrimitiveException.Unavailable(message) : createException(); } },
private void onStateChange(PrimitiveState state) { if (state != PrimitiveState.CONNECTED) { for (LockAttempt attempt : attempts.values()) { getProxyClient().acceptBy(name(), service -> service.unlock(attempt.id())); attempt.completeExceptionally(new PrimitiveException.Unavailable()); } } }
@Override PrimitiveException createException(String message) { return message != null ? new PrimitiveException.Unavailable(message) : createException(); } };
@Override PrimitiveException createException(String message) { return message != null ? new PrimitiveException.Unavailable(message) : createException(); } },
@Override PrimitiveException createException(String message) { return message != null ? new PrimitiveException.Unavailable(message) : createException(); } },
@Override PrimitiveException createException(String message) { return message != null ? new PrimitiveException.Unavailable(message) : createException(); } },