com.datastax.driver.core.ExecutionInfo Maven / Gradle / Ivy
Show all versions of dse-java-driver-core Show documentation
/*
* Copyright DataStax, Inc.
*
* This software can be used solely with DataStax Enterprise. Please consult the license at
* http://www.datastax.com/terms/datastax-dse-driver-license-terms
*/
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;
}
}