Example #1
0
  /**
   * Submits a query via the session.
   *
   * @param query The query to submit.
   * @param <T> The query output type.
   * @return A completable future to be completed with the query output.
   */
  public <T> CompletableFuture<T> submit(Query<T> query) {
    if (!isOpen()) return Futures.exceptionalFuture(new IllegalStateException("session not open"));

    CompletableFuture<T> future = new CompletableFuture<>();
    context
        .executor()
        .execute(
            () -> {
              QueryRequest request;
              if (query.consistency() == Query.ConsistencyLevel.CAUSAL) {
                request =
                    QueryRequest.builder()
                        .withSession(id)
                        .withSequence(commandResponse)
                        .withVersion(responseVersion)
                        .withQuery(query)
                        .build();
              } else {
                request =
                    QueryRequest.builder()
                        .withSession(id)
                        .withSequence(commandRequest)
                        .withVersion(responseVersion)
                        .withQuery(query)
                        .build();
              }

              submit(request, future);
            });
    return future;
  }
Example #2
0
  /** Recursively submits a query. */
  @SuppressWarnings("unchecked")
  private <T> CompletableFuture<T> submit(QueryRequest request, CompletableFuture<T> future) {
    if (!isOpen()) {
      future.completeExceptionally(new IllegalStateException("session not open"));
      return future;
    }

    long sequence = ++requestSequence;

    this.<QueryRequest, QueryResponse>request(request)
        .whenComplete(
            (response, error) -> {
              if (error == null) {
                // If the query consistency level is CAUSAL, we can simply complete queries in
                // sequential order.
                if (request.query().consistency() == Query.ConsistencyLevel.CAUSAL) {
                  sequenceResponse(
                      sequence,
                      () -> {
                        responseVersion = Math.max(responseVersion, response.version());
                        completeResponse(response, future);
                      });
                }
                // If the query consistency level is strong, the query must be executed
                // sequentially. In order to ensure responses
                // are received in a sequential manner, we compare the response version number with
                // the highest version for which
                // we've received a response and resubmit queries with output resulting from stale
                // (prior) versions.
                else {
                  sequenceResponse(
                      sequence,
                      () -> {
                        if (response.version() > 0 && response.version() < responseVersion) {
                          submit(request, future);
                        } else {
                          responseVersion = Math.max(responseVersion, response.version());
                          completeResponse(response, future);
                        }
                      });
                }
              } else {
                future.completeExceptionally(error);
              }
            });
    return future;
  }