/** * Submits a command via the session. * * @param command The command to submit. * @param <T> The command output type. * @return A completable future to be completed with the command output. */ public <T> CompletableFuture<T> submit(Command<T> command) { if (!isOpen()) return Futures.exceptionalFuture(new IllegalStateException("session not open")); CompletableFuture<T> future = new CompletableFuture<>(); context .executor() .execute( () -> { CommandRequest request; if (command.consistency() == Command.ConsistencyLevel.NONE) { request = CommandRequest.builder() .withSession(id) .withSequence(0) .withCommand(command) .build(); } else { request = CommandRequest.builder() .withSession(id) .withSequence(++commandRequest) .withCommand(command) .build(); } submit(request, future); }); return future; }
/** Recursively submits a command. */ @SuppressWarnings("unchecked") private <T> CompletableFuture<T> submit(CommandRequest request, CompletableFuture<T> future) { if (!isOpen()) { future.completeExceptionally(new IllegalStateException("session not open")); return future; } long sequence = ++requestSequence; this.<CommandRequest, CommandResponse>request(request) .whenComplete( (response, error) -> { if (error == null) { long responseSequence = request.sequence(); sequenceResponse( sequence, () -> { commandResponse = responseSequence; completeResponse(response, future); }); } else { future.completeExceptionally(error); } }); return future; }