Skip to content

Commit

Permalink
perf: only capture the call stack if the call is actually async (#2471)
Browse files Browse the repository at this point in the history
Only capture the call stack of a caller of one of the Connection API methods if the top-level call was an async call. For synchronous calls, we do not need to additionally capture the call stack, as any exception will include the current call stack of the synchronous method call.
  • Loading branch information
olavloite committed May 31, 2023
1 parent 7c23729 commit ae9c8ad
Show file tree
Hide file tree
Showing 16 changed files with 562 additions and 260 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,12 @@ public void cancel() {
}

<T> ApiFuture<T> executeStatementAsync(
CallType callType,
ParsedStatement statement,
Callable<T> callable,
@Nullable MethodDescriptor<?, ?> applyStatementTimeoutToMethod) {
return executeStatementAsync(
callType,
statement,
callable,
InterceptorsUsage.INVOKE_INTERCEPTORS,
Expand All @@ -190,11 +192,16 @@ <T> ApiFuture<T> executeStatementAsync(
}

<T> ApiFuture<T> executeStatementAsync(
CallType callType,
ParsedStatement statement,
Callable<T> callable,
Collection<MethodDescriptor<?, ?>> applyStatementTimeoutToMethods) {
return executeStatementAsync(
statement, callable, InterceptorsUsage.INVOKE_INTERCEPTORS, applyStatementTimeoutToMethods);
callType,
statement,
callable,
InterceptorsUsage.INVOKE_INTERCEPTORS,
applyStatementTimeoutToMethods);
}

<ResponseT, MetadataT> ResponseT getWithStatementTimeout(
Expand Down Expand Up @@ -237,6 +244,7 @@ <ResponseT, MetadataT> ResponseT getWithStatementTimeout(
}

<T> ApiFuture<T> executeStatementAsync(
CallType callType,
ParsedStatement statement,
Callable<T> callable,
InterceptorsUsage interceptorUsage,
Expand Down Expand Up @@ -268,13 +276,17 @@ public <ReqT, RespT> ApiCallContext configure(
}
ApiFuture<T> f = statementExecutor.submit(context.wrap(callable));
final SpannerAsyncExecutionException caller =
new SpannerAsyncExecutionException(statement.getStatement());
callType == CallType.ASYNC
? new SpannerAsyncExecutionException(statement.getStatement())
: null;
final ApiFuture<T> future =
ApiFutures.catching(
f,
Throwable.class,
input -> {
input.addSuppressed(caller);
if (caller != null) {
input.addSuppressed(caller);
}
throw SpannerExceptionFactory.asSpannerException(input);
},
MoreExecutors.directExecutor());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,21 @@ public boolean isActive() {
* Check that the current transaction actually has a valid underlying transaction. If not, the
* method will throw a {@link SpannerException}.
*/
abstract void checkValidTransaction();
abstract void checkValidTransaction(CallType callType);

/** Returns the {@link ReadContext} that can be used for queries on this transaction. */
abstract ReadContext getReadContext();

@Override
public ApiFuture<ResultSet> executeQueryAsync(
final CallType callType,
final ParsedStatement statement,
final AnalyzeMode analyzeMode,
final QueryOption... options) {
Preconditions.checkArgument(statement.isQuery(), "Statement is not a query");
checkValidTransaction();
checkValidTransaction(callType);
return executeStatementAsync(
callType,
statement,
() -> {
checkAborted();
Expand All @@ -133,7 +136,7 @@ ResultSet internalExecuteQuery(
}

@Override
public ApiFuture<long[]> runBatchAsync() {
public ApiFuture<long[]> runBatchAsync(CallType callType) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.FAILED_PRECONDITION, "Run batch is not supported for transactions");
}
Expand Down
Loading

0 comments on commit ae9c8ad

Please sign in to comment.