Skip to content

Commit 2e8a0ee

Browse files
committed
chore: add otel integration to retry context
1 parent 5c2cf19 commit 2e8a0ee

File tree

3 files changed

+52
-5
lines changed

3 files changed

+52
-5
lines changed

google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageOptions.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@
119119
import java.util.Set;
120120
import java.util.concurrent.ScheduledExecutorService;
121121
import java.util.function.Function;
122-
import java.util.function.UnaryOperator;
123122
import java.util.logging.Logger;
124123
import org.checkerframework.checker.nullness.qual.NonNull;
125124

@@ -838,7 +837,9 @@ public Storage create(StorageOptions options) {
838837
grpcStorageOptions.getRetryAlgorithmManager().idempotent()));
839838

840839
OpenTelemetry otel = options.getOpenTelemetry();
841-
DefaultRetrier retrier = new DefaultRetrier(UnaryOperator.identity(), grpcStorageOptions);
840+
DefaultRetrier retrier =
841+
new DefaultRetrier(
842+
OtelStorageDecorator.retryContextDecorator(otel), grpcStorageOptions);
842843
if (ZeroCopyReadinessChecker.isReady()) {
843844
LOGGER.config("zero-copy protobuf deserialization available, using it");
844845
StorageStubSettings baseSettings =

google-cloud-storage/src/main/java/com/google/cloud/storage/HttpStorageOptions.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import java.time.Clock;
5050
import java.util.Objects;
5151
import java.util.Set;
52-
import java.util.function.UnaryOperator;
5352
import org.checkerframework.checker.nullness.qual.NonNull;
5453

5554
/** @since 2.14.0 */
@@ -405,7 +404,7 @@ public Storage create(StorageOptions options) {
405404
factory,
406405
new HttpRetrier(
407406
new DefaultRetrier(
408-
UnaryOperator.identity(),
407+
OtelStorageDecorator.retryContextDecorator(otel),
409408
RetryingDependencies.simple(
410409
options.getClock(), options.getRetrySettings()))));
411410
return OtelStorageDecorator.decorate(storage, otel, Transport.HTTP);

google-cloud-storage/src/main/java/com/google/cloud/storage/OtelStorageDecorator.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import java.util.List;
6060
import java.util.Locale;
6161
import java.util.concurrent.TimeUnit;
62+
import java.util.function.UnaryOperator;
6263
import org.checkerframework.checker.nullness.qual.NonNull;
6364
import org.checkerframework.checker.nullness.qual.Nullable;
6465

@@ -1520,6 +1521,14 @@ static Storage decorate(Storage delegate, OpenTelemetry otel, Transport transpor
15201521
return new OtelStorageDecorator(delegate, otel, baseAttributes);
15211522
}
15221523

1524+
static UnaryOperator<RetryContext> retryContextDecorator(OpenTelemetry otel) {
1525+
requireNonNull(otel, "otel must be non null");
1526+
if (otel == OpenTelemetry.noop()) {
1527+
return UnaryOperator.identity();
1528+
}
1529+
return ctx -> new OtelRetryContextDecorator(ctx, Span.current());
1530+
}
1531+
15231532
private static @NonNull String fmtBucket(String bucket) {
15241533
return String.format(Locale.US, "gs://%s/", bucket);
15251534
}
@@ -1826,8 +1835,10 @@ private class OtelBaseConfigDecorator
18261835
@Override
18271836
ObjectReadSessionStreamRead<Projection> newRead(
18281837
long readId, RangeSpec range, RetryContext retryContext) {
1838+
OtelRetryContextDecorator otelRetryContext =
1839+
new OtelRetryContextDecorator(retryContext, parentSpan);
18291840
ObjectReadSessionStreamRead<Projection> read =
1830-
delegate.newRead(readId, range, retryContext);
1841+
delegate.newRead(readId, range, otelRetryContext);
18311842
read.setOnCloseCallback(parentSpan::end);
18321843
return new OtelDecoratingObjectReadSessionStreamRead<>(read, parentSpan);
18331844
}
@@ -1839,6 +1850,42 @@ ObjectReadSessionStreamRead<Projection> newRead(
18391850
}
18401851
}
18411852

1853+
private static final class OtelRetryContextDecorator implements RetryContext {
1854+
private final RetryContext delegate;
1855+
private final Span span;
1856+
1857+
private OtelRetryContextDecorator(RetryContext delegate, Span span) {
1858+
this.delegate = delegate;
1859+
this.span = span;
1860+
}
1861+
1862+
@Override
1863+
public boolean inBackoff() {
1864+
return delegate.inBackoff();
1865+
}
1866+
1867+
@Override
1868+
public void reset() {
1869+
delegate.reset();
1870+
}
1871+
1872+
@Override
1873+
public <T extends Throwable> void recordError(
1874+
T t, OnSuccess onSuccess, OnFailure<T> onFailure) {
1875+
span.recordException(t);
1876+
delegate.recordError(
1877+
t,
1878+
() -> {
1879+
span.addEvent("retrying");
1880+
onSuccess.onSuccess();
1881+
},
1882+
(tt) -> {
1883+
span.addEvent("terminal_failure");
1884+
onFailure.onFailure(tt);
1885+
});
1886+
}
1887+
}
1888+
18421889
@VisibleForTesting
18431890
class OtelDecoratingBlobReadSession implements BlobReadSession {
18441891

0 commit comments

Comments
 (0)