All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.driver.core.ExecutionInfo Maven / Gradle / Ivy

/*
 * Copyright DataStax, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.datastax.driver.core;

import com.datastax.driver.core.utils.Bytes;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/** Basic information on the execution of a query. */
public class ExecutionInfo {
  private final int speculativeExecutions;
  private final int successfulExecutionIndex;
  private final List triedHosts;
  private final ConsistencyLevel achievedConsistency;
  private final QueryTrace trace;
  private final ByteBuffer pagingState;
  private final ProtocolVersion protocolVersion;
  private final CodecRegistry codecRegistry;
  private final Statement statement;
  private volatile boolean schemaInAgreement;
  private final List warnings;
  private final Map incomingPayload;

  private ExecutionInfo(
      int speculativeExecutions,
      int successfulExecutionIndex,
      List triedHosts,
      ConsistencyLevel achievedConsistency,
      QueryTrace trace,
      ByteBuffer pagingState,
      ProtocolVersion protocolVersion,
      CodecRegistry codecRegistry,
      Statement statement,
      boolean schemaAgreement,
      List warnings,
      Map incomingPayload) {
    this.speculativeExecutions = speculativeExecutions;
    this.successfulExecutionIndex = successfulExecutionIndex;
    this.triedHosts = triedHosts;
    this.achievedConsistency = achievedConsistency;
    this.trace = trace;
    this.pagingState = pagingState;
    this.protocolVersion = protocolVersion;
    this.codecRegistry = codecRegistry;
    this.statement = statement;
    this.schemaInAgreement = schemaAgreement;
    this.warnings = warnings;
    this.incomingPayload = incomingPayload;
  }

  ExecutionInfo(Host singleHost) {
    this(
        0,
        0,
        ImmutableList.of(singleHost),
        null,
        null,
        null,
        null,
        null,
        null,
        true,
        Collections.emptyList(),
        null);
  }

  public ExecutionInfo(
      int speculativeExecutions,
      int successfulExecutionIndex,
      List triedHosts,
      ConsistencyLevel achievedConsistency,
      Map customPayload) {
    this(
        speculativeExecutions,
        successfulExecutionIndex,
        triedHosts,
        achievedConsistency,
        null,
        null,
        null,
        null,
        null,
        false,
        null,
        customPayload);
  }

  ExecutionInfo with(
      QueryTrace newTrace,
      List newWarnings,
      ByteBuffer newPagingState,
      Statement newStatement,
      ProtocolVersion protocolVersion,
      CodecRegistry codecRegistry) {
    return new ExecutionInfo(
        speculativeExecutions,
        successfulExecutionIndex,
        triedHosts,
        achievedConsistency,
        newTrace,
        newPagingState,
        protocolVersion,
        codecRegistry,
        newStatement,
        schemaInAgreement,
        newWarnings,
        incomingPayload);
  }

  /**
   * The list of tried hosts for this query.
   *
   * 

In general, this will be a singleton list with the host that coordinated that query. * However: * *

    *
  • if a host is tried by the driver but is dead or in error, that host is recorded and the * query is retried; *
  • on a timeout or unavailable exception, some {@link * com.datastax.driver.core.policies.RetryPolicy} may retry the query on the same host, so * the same host might appear twice. *
  • if {@link com.datastax.driver.core.policies.SpeculativeExecutionPolicy speculative * executions} are enabled, this will also contain hosts that were tried by other executions * (however, note that this only contains hosts which timed out, or for which a response was * received; if an execution is waiting for a response from a host and another execution * completes the request in the meantime, then the host of the first execution will not be * in that list). *
* *

If you are only interested in fetching the final (and often only) node coordinating the * query, {@link #getQueriedHost} provides a shortcut to fetch the last element of the list * returned by this method. * * @return the list of tried hosts for this query, in the order tried. */ public List getTriedHosts() { return triedHosts; } /** * Return the Cassandra host that coordinated this query. * *

This is a shortcut for {@code getTriedHosts().get(getTriedHosts().size() - 1)}. * * @return return the Cassandra host that coordinated this query. */ public Host getQueriedHost() { return triedHosts.get(triedHosts.size() - 1); } /** * The number of speculative executions that were started for this query. * *

This does not include the initial, normal execution of the query. Therefore, if speculative * executions are disabled, this will always be 0. If they are enabled and one speculative * execution was triggered in addition to the initial execution, this will be 1, etc. * * @see #getSuccessfulExecutionIndex() * @see * Cluster.Builder#withSpeculativeExecutionPolicy(com.datastax.driver.core.policies.SpeculativeExecutionPolicy) */ public int getSpeculativeExecutions() { return speculativeExecutions; } /** * The index of the execution that completed this query. * *

0 represents the initial, normal execution of the query, 1 represents the first speculative * execution, etc. * * @see #getSpeculativeExecutions() * @see * Cluster.Builder#withSpeculativeExecutionPolicy(com.datastax.driver.core.policies.SpeculativeExecutionPolicy) */ public int getSuccessfulExecutionIndex() { return successfulExecutionIndex; } /** * If the query returned without achieving the requested consistency level due to the {@link * com.datastax.driver.core.policies.RetryPolicy}, this return the biggest consistency level that * has been actually achieved by the query. * *

Note that the default {@code RetryPolicy} ({@link * com.datastax.driver.core.policies.DefaultRetryPolicy}) will never allow a query to be * successful without achieving the initially requested consistency level and hence with that * default policy, this method will always return {@code null}. However, it might * occasionally return a non-{@code null} with say, {@link * com.datastax.driver.core.policies.DowngradingConsistencyRetryPolicy}. * * @return {@code null} if the original consistency level of the query was achieved, or the * consistency level that was ultimately achieved if the {@code RetryPolicy} triggered a retry * at a different consistency level than the original one. */ public ConsistencyLevel getAchievedConsistencyLevel() { return achievedConsistency; } /** * Return the query trace if tracing was enabled on this query. * *

Note that accessing the fields of the the returned object will trigger a blocking * background query. * * @return the {@code QueryTrace} object for this query if tracing was enable for this query, or * {@code null} otherwise. */ public QueryTrace getQueryTrace() { return trace; } /** * Placeholder for async query trace retrieval (not implemented yet). * *

Async query trace retrieval will be implemented in a future version. This method is added * now to avoid breaking binary compatibility later. The current implementation merely wraps the * result of {@link #getQueryTrace()} in an immediate future; it will still trigger a blocking * query when the query trace's fields are accessed. * * @return currently, an immediate future containing the result of {@link #getQueryTrace()}. */ public ListenableFuture getQueryTraceAsync() { return Futures.immediateFuture(trace); } /** * The paging state of the query. * *

This object represents the next page to be fetched if this query is multi page. It can be * saved and reused later on the same statement. * * @return the paging state or null if there is no next page. * @see Statement#setPagingState(PagingState) */ public PagingState getPagingState() { if (this.pagingState == null) return null; return new PagingState( this.pagingState, this.statement, this.protocolVersion, this.codecRegistry); } /** * Returns the "raw" paging state of the query. * *

Contrary to {@link #getPagingState()}, there will be no validation when this is later * reinjected into a statement. * * @return the paging state or null if there is no next page. * @see Statement#setPagingStateUnsafe(byte[]) */ public byte[] getPagingStateUnsafe() { if (this.pagingState == null) return null; return Bytes.getArray(this.pagingState); } /** * Whether the cluster had reached schema agreement after the execution of this query. * *

After a successful schema-altering query (ex: creating a table), the driver will check if * the cluster's nodes agree on the new schema version. If not, it will keep retrying for a given * delay (configurable via {@link Cluster.Builder#withMaxSchemaAgreementWaitSeconds(int)}). * *

If this method returns {@code false}, clients can call {@link * Metadata#checkSchemaAgreement()} later to perform the check manually. * *

Note that the schema agreement check is only performed for schema-altering queries For other * query types, this method will always return {@code true}. * * @return whether the cluster reached schema agreement, or {@code true} for a non schema-altering * statement. */ public boolean isSchemaInAgreement() { return schemaInAgreement; } void setSchemaInAgreement(boolean schemaAgreement) { this.schemaInAgreement = schemaAgreement; } /** * Returns the server-side warnings for this query. * *

This feature is only available with {@link ProtocolVersion#V4} or above; with lower * versions, the returned list will always be empty. * * @return the warnings, or an empty list if there are none. * @since 2.2 */ public List getWarnings() { return warnings; } /** * Return the incoming payload, that is, the payload that the server sent back with its response, * if any, or {@code null}, if the server did not include any custom payload. * *

This method returns a read-only view of the original map, but its values remain inherently * mutable. Callers should take care not to modify the returned map in any way. * *

This feature is only available with {@link ProtocolVersion#V4} or above; with lower * versions, this method will always return {@code null}. * * @return the custom payload that the server sent back with its response, if any, or {@code * null}, if the server did not include any custom payload. * @since 2.2 */ public Map getIncomingPayload() { return incomingPayload; } /** * Get the statement that has been executed. * * @return the statement executed. */ public Statement getStatement() { return this.statement; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy