com.datastax.oss.driver.api.core.cql.ExecutionInfo Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.oss.driver.api.core.cql;
import com.datastax.oss.driver.api.core.DefaultProtocolVersion;
import com.datastax.oss.driver.api.core.DriverException;
import com.datastax.oss.driver.api.core.RequestThrottlingException;
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
import com.datastax.oss.driver.api.core.detach.AttachmentPoint;
import com.datastax.oss.driver.api.core.metadata.Node;
import com.datastax.oss.driver.api.core.retry.RetryDecision;
import com.datastax.oss.driver.api.core.servererrors.CoordinatorException;
import com.datastax.oss.driver.api.core.session.Request;
import com.datastax.oss.driver.api.core.session.Session;
import com.datastax.oss.driver.api.core.specex.SpeculativeExecutionPolicy;
import com.datastax.oss.driver.internal.core.cql.DefaultPagingState;
import com.datastax.oss.driver.internal.core.util.concurrent.BlockingOperation;
import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletionStage;
/**
* Information about the execution of a query.
*
* This can be obtained either from a result set for a successful query, or from a driver
* exception for a failed query.
*
* @see ResultSet#getExecutionInfo()
* @see DriverException#getExecutionInfo()
*/
public interface ExecutionInfo {
/** @return The {@link Request} that was executed. */
@NonNull
default Request getRequest() {
return getStatement();
}
/**
* @return The {@link Request} that was executed, if it can be cast to {@link Statement}.
* @deprecated Use {@link #getRequest()} instead.
* @throws ClassCastException If the request that was executed cannot be cast to {@link
* Statement}.
*/
@NonNull
@Deprecated
Statement getStatement();
/**
* The node that acted as a coordinator for the query.
*
*
For successful queries, this is never {@code null}. It is the node that sent the response
* from which the result was decoded.
*
*
For failed queries, this can either be {@code null} if the error occurred before any node
* could be contacted (for example a {@link RequestThrottlingException}), or present if a node was
* successfully contacted, but replied with an error response (any subclass of {@link
* CoordinatorException}).
*/
@Nullable
Node getCoordinator();
/**
* 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 SpeculativeExecutionPolicy
*/
int getSpeculativeExecutionCount();
/**
* The index of the execution that completed this query.
*
*
0 represents the initial, normal execution of the query, 1 the first speculative execution,
* etc. If this execution info is attached to an error, this might not be applicable, and will
* return -1.
*
* @see SpeculativeExecutionPolicy
*/
int getSuccessfulExecutionIndex();
/**
* The errors encountered on previous coordinators, if any.
*
*
The list is in chronological order, based on the time that the driver processed the error
* responses. If speculative executions are enabled, they run concurrently so their errors will be
* interleaved. A node can appear multiple times (if the retry policy decided to retry on the same
* node).
*/
@NonNull
List> getErrors();
/**
* The paging state of the query, in its raw form.
*
* This represents the next page to be fetched if this query has multiple page of results. It
* can be saved and reused later on the same statement.
*
*
Note that this is the equivalent of driver 3's {@code getPagingStateUnsafe()}. If you're
* looking for the method that returns a {@link PagingState}, use {@link #getSafePagingState()}.
*
* @return the paging state, or {@code null} if there is no next page.
*/
@Nullable
ByteBuffer getPagingState();
/**
* The paging state of the query, in a safe wrapper that checks if it's reused on the right
* statement.
*
*
This represents the next page to be fetched if this query has multiple page of results. It
* can be saved and reused later on the same statement.
*
* @return the paging state, or {@code null} if there is no next page.
*/
@Nullable
default PagingState getSafePagingState() {
// Default implementation for backward compatibility, but we override it in the concrete class,
// because it knows the attachment point.
ByteBuffer rawPagingState = getPagingState();
if (rawPagingState == null) {
return null;
} else {
Request request = getRequest();
if (!(request instanceof Statement)) {
throw new IllegalStateException("Only statements should have a paging state");
}
Statement statement = (Statement) request;
return new DefaultPagingState(rawPagingState, statement, AttachmentPoint.NONE);
}
}
/**
* The server-side warnings for this query, if any (otherwise the list will be empty).
*
*
This feature is only available with {@link DefaultProtocolVersion#V4} or above; with lower
* versions, this list will always be empty.
*/
@NonNull
List getWarnings();
/**
* The custom payload sent back by the server with the response, if any (otherwise the map will be
* empty).
*
* This method returns a read-only view of the original map, but its values remain inherently
* mutable. If multiple clients will read these values, care should be taken not to corrupt the
* data (in particular, preserve the indices by calling {@link ByteBuffer#duplicate()}).
*
*
This feature is only available with {@link DefaultProtocolVersion#V4} or above; with lower
* versions, this map will always be empty.
*/
@NonNull
Map getIncomingPayload();
/**
* Whether the cluster 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 a few times
* (the retry delay and timeout are set through the configuration).
*
*
If this method returns {@code false}, clients can call {@link
* Session#checkSchemaAgreement()} later to perform the check manually.
*
*
Schema agreement is only checked for schema-altering queries. For other query types, this
* method will always return {@code true}.
*
* @see DefaultDriverOption#CONTROL_CONNECTION_AGREEMENT_INTERVAL
* @see DefaultDriverOption#CONTROL_CONNECTION_AGREEMENT_TIMEOUT
*/
boolean isSchemaInAgreement();
/**
* The tracing identifier if tracing was {@link Statement#isTracing() enabled} for this query,
* otherwise {@code null}.
*/
@Nullable
UUID getTracingId();
/**
* Fetches the query trace asynchronously, if tracing was enabled for this query.
*
*
Note that each call to this method triggers a new fetch, even if the previous call was
* successful (this allows fetching the trace again if the list of {@link QueryTrace#getEvents()
* events} was incomplete).
*
*
This method will return a failed future if tracing was disabled for the query (that is, if
* {@link #getTracingId()} is null).
*/
@NonNull
CompletionStage getQueryTraceAsync();
/**
* Convenience method to call {@link #getQueryTraceAsync()} and block for the result.
*
* This must not be called on a driver thread.
*
* @throws IllegalStateException if {@link #getTracingId()} is null.
*/
@NonNull
default QueryTrace getQueryTrace() {
BlockingOperation.checkNotDriverThread();
return CompletableFutures.getUninterruptibly(getQueryTraceAsync());
}
/**
* The size of the binary response in bytes.
*
*
This is the size of the protocol-level frame (including the frame header) before it was
* decoded by the driver, but after decompression (if compression is enabled).
*
*
If the information is not available (for example if this execution info comes from an {@link
* RetryDecision#IGNORE IGNORE} decision of the retry policy), this method returns -1.
*
* @see #getCompressedResponseSizeInBytes()
*/
int getResponseSizeInBytes();
/**
* The size of the compressed binary response in bytes.
*
*
This is the size of the protocol-level frame (including the frame header) as it came in the
* TCP response, before decompression and decoding by the driver.
*
*
If compression is disabled, or if the information is not available (for example if this
* execution info comes from an {@link RetryDecision#IGNORE IGNORE} decision of the retry policy),
* this method returns -1.
*
* @see #getResponseSizeInBytes()
*/
int getCompressedResponseSizeInBytes();
}