Skip to content

Commit 2ae5ca0

Browse files
authored
Spanner: Use gax for retries (#4940)
Rely on standard gax logic for retrying grpc calls. The custom retry logic of the Spanner client has been replaced and now uses the standard gax retry logic. This also allows the user to set custom retry settings on SpannerOptions.
1 parent 722508f commit 2ae5ca0

18 files changed

Lines changed: 2022 additions & 456 deletions

google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractReadContext.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import io.opencensus.trace.Span;
4444
import io.opencensus.trace.Tracing;
4545
import java.util.Map;
46-
import java.util.concurrent.Callable;
4746
import java.util.concurrent.atomic.AtomicLong;
4847
import javax.annotation.Nullable;
4948
import javax.annotation.concurrent.GuardedBy;
@@ -226,14 +225,7 @@ void initTransaction() {
226225
.setSession(session.getName())
227226
.setOptions(options)
228227
.build();
229-
Transaction transaction =
230-
SpannerImpl.runWithRetries(
231-
new Callable<Transaction>() {
232-
@Override
233-
public Transaction call() throws Exception {
234-
return rpc.beginTransaction(request, session.getOptions());
235-
}
236-
});
228+
Transaction transaction = rpc.beginTransaction(request, session.getOptions());
237229
if (!transaction.hasReadTimestamp()) {
238230
throw SpannerExceptionFactory.newSpannerException(
239231
ErrorCode.INTERNAL, "Missing expected transaction.read_timestamp metadata field");

google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchClientImpl.java

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import com.google.spanner.v1.TransactionSelector;
3333
import java.util.List;
3434
import java.util.Map;
35-
import java.util.concurrent.Callable;
3635

3736
/** Default implementation for Batch Client interface. */
3837
public class BatchClientImpl implements BatchClient {
@@ -135,14 +134,7 @@ public List<Partition> partitionReadUsingIndex(
135134
builder.setPartitionOptions(pbuilder.build());
136135

137136
final PartitionReadRequest request = builder.build();
138-
PartitionResponse response =
139-
SpannerImpl.runWithRetries(
140-
new Callable<PartitionResponse>() {
141-
@Override
142-
public PartitionResponse call() throws Exception {
143-
return rpc.partitionRead(request, options);
144-
}
145-
});
137+
PartitionResponse response = rpc.partitionRead(request, options);
146138
ImmutableList.Builder<Partition> partitions = ImmutableList.builder();
147139
for (com.google.spanner.v1.Partition p : response.getPartitionsList()) {
148140
Partition partition =
@@ -180,14 +172,7 @@ public List<Partition> partitionQuery(
180172
builder.setPartitionOptions(pbuilder.build());
181173

182174
final PartitionQueryRequest request = builder.build();
183-
PartitionResponse response =
184-
SpannerImpl.runWithRetries(
185-
new Callable<PartitionResponse>() {
186-
@Override
187-
public PartitionResponse call() throws Exception {
188-
return rpc.partitionQuery(request, options);
189-
}
190-
});
175+
PartitionResponse response = rpc.partitionQuery(request, options);
191176
ImmutableList.Builder<Partition> partitions = ImmutableList.builder();
192177
for (com.google.spanner.v1.Partition p : response.getPartitionsList()) {
193178
Partition partition =

google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata;
3333
import java.util.List;
3434
import java.util.UUID;
35-
import java.util.concurrent.Callable;
3635
import javax.annotation.Nullable;
3736

3837
/** Default implementation of {@link DatabaseAdminClient}. */
@@ -83,15 +82,8 @@ public Database apply(Exception e) {
8382

8483
@Override
8584
public Database getDatabase(String instanceId, String databaseId) throws SpannerException {
86-
final String dbName = getDatabaseName(instanceId, databaseId);
87-
Callable<Database> callable =
88-
new Callable<Database>() {
89-
@Override
90-
public Database call() throws Exception {
91-
return Database.fromProto(rpc.getDatabase(dbName), DatabaseAdminClientImpl.this);
92-
}
93-
};
94-
return SpannerImpl.runWithRetries(callable);
85+
String dbName = getDatabaseName(instanceId, databaseId);
86+
return Database.fromProto(rpc.getDatabase(dbName), DatabaseAdminClientImpl.this);
9587
}
9688

9789
@Override
@@ -126,29 +118,14 @@ public Void apply(Exception e) {
126118

127119
@Override
128120
public void dropDatabase(String instanceId, String databaseId) throws SpannerException {
129-
final String dbName = getDatabaseName(instanceId, databaseId);
130-
Callable<Void> callable =
131-
new Callable<Void>() {
132-
@Override
133-
public Void call() throws Exception {
134-
rpc.dropDatabase(dbName);
135-
return null;
136-
}
137-
};
138-
SpannerImpl.runWithRetries(callable);
121+
String dbName = getDatabaseName(instanceId, databaseId);
122+
rpc.dropDatabase(dbName);
139123
}
140124

141125
@Override
142126
public List<String> getDatabaseDdl(String instanceId, String databaseId) {
143-
final String dbName = getDatabaseName(instanceId, databaseId);
144-
Callable<List<String>> callable =
145-
new Callable<List<String>>() {
146-
@Override
147-
public List<String> call() throws Exception {
148-
return rpc.getDatabaseDdl(dbName);
149-
}
150-
};
151-
return SpannerImpl.runWithRetries(callable);
127+
String dbName = getDatabaseName(instanceId, databaseId);
128+
return rpc.getDatabaseDdl(dbName);
152129
}
153130

154131
@Override

google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceAdminClientImpl.java

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import com.google.protobuf.FieldMask;
3232
import com.google.spanner.admin.instance.v1.CreateInstanceMetadata;
3333
import com.google.spanner.admin.instance.v1.UpdateInstanceMetadata;
34-
import java.util.concurrent.Callable;
3534

3635
/** Default implementation of {@link InstanceAdminClient} */
3736
class InstanceAdminClientImpl implements InstanceAdminClient {
@@ -49,15 +48,9 @@ class InstanceAdminClientImpl implements InstanceAdminClient {
4948

5049
@Override
5150
public InstanceConfig getInstanceConfig(String configId) throws SpannerException {
52-
final String instanceConfigName = new InstanceConfigId(projectId, configId).getName();
53-
return SpannerImpl.runWithRetries(
54-
new Callable<InstanceConfig>() {
55-
@Override
56-
public InstanceConfig call() {
57-
return InstanceConfig.fromProto(
58-
rpc.getInstanceConfig(instanceConfigName), InstanceAdminClientImpl.this);
59-
}
60-
});
51+
String instanceConfigName = new InstanceConfigId(projectId, configId).getName();
52+
return InstanceConfig.fromProto(
53+
rpc.getInstanceConfig(instanceConfigName), InstanceAdminClientImpl.this);
6154
}
6255

6356
@Override
@@ -119,15 +112,9 @@ public Instance apply(Exception e) {
119112

120113
@Override
121114
public Instance getInstance(String instanceId) throws SpannerException {
122-
final String instanceName = new InstanceId(projectId, instanceId).getName();
123-
return SpannerImpl.runWithRetries(
124-
new Callable<Instance>() {
125-
@Override
126-
public Instance call() {
127-
return Instance.fromProto(
128-
rpc.getInstance(instanceName), InstanceAdminClientImpl.this, dbClient);
129-
}
130-
});
115+
String instanceName = new InstanceId(projectId, instanceId).getName();
116+
return Instance.fromProto(
117+
rpc.getInstance(instanceName), InstanceAdminClientImpl.this, dbClient);
131118
}
132119

133120
@Override
@@ -156,14 +143,7 @@ public Instance fromProto(com.google.spanner.admin.instance.v1.Instance proto) {
156143

157144
@Override
158145
public void deleteInstance(final String instanceId) throws SpannerException {
159-
SpannerImpl.runWithRetries(
160-
new Callable<Void>() {
161-
@Override
162-
public Void call() {
163-
rpc.deleteInstance(new InstanceId(projectId, instanceId).getName());
164-
return null;
165-
}
166-
});
146+
rpc.deleteInstance(new InstanceId(projectId, instanceId).getName());
167147
}
168148

169149
@Override

google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/PartitionedDMLTransaction.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import com.google.spanner.v1.TransactionOptions;
2929
import com.google.spanner.v1.TransactionSelector;
3030
import java.util.Map;
31-
import java.util.concurrent.Callable;
3231

3332
/** Partitioned DML transaction for bulk updates and deletes. */
3433
class PartitionedDMLTransaction implements SessionTransaction {
@@ -51,14 +50,7 @@ private ByteString initTransaction() {
5150
TransactionOptions.newBuilder()
5251
.setPartitionedDml(TransactionOptions.PartitionedDml.getDefaultInstance()))
5352
.build();
54-
Transaction txn =
55-
SpannerImpl.runWithRetries(
56-
new Callable<Transaction>() {
57-
@Override
58-
public Transaction call() throws Exception {
59-
return rpc.beginTransaction(request, session.getOptions());
60-
}
61-
});
53+
Transaction txn = rpc.beginTransaction(request, session.getOptions());
6254
if (txn.getId().isEmpty()) {
6355
throw SpannerExceptionFactory.newSpannerException(
6456
ErrorCode.INTERNAL,
@@ -84,13 +76,7 @@ long executePartitionedUpdate(Statement statement) {
8476
}
8577
}
8678
com.google.spanner.v1.ResultSet resultSet =
87-
SpannerImpl.runWithRetries(
88-
new Callable<com.google.spanner.v1.ResultSet>() {
89-
@Override
90-
public com.google.spanner.v1.ResultSet call() throws Exception {
91-
return rpc.executeQuery(builder.build(), session.getOptions());
92-
}
93-
});
79+
rpc.executeQuery(builder.build(), session.getOptions());
9480
if (!resultSet.hasStats()) {
9581
throw new IllegalArgumentException(
9682
"Partitioned DML response missing stats possibly due to non-DML statement as input");

google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import java.util.Collection;
4141
import java.util.List;
4242
import java.util.Map;
43-
import java.util.concurrent.Callable;
4443
import javax.annotation.Nullable;
4544

4645
/**
@@ -137,14 +136,7 @@ public Timestamp writeAtLeastOnce(Iterable<Mutation> mutations) throws SpannerEx
137136
.build();
138137
Span span = tracer.spanBuilder(SpannerImpl.COMMIT).startSpan();
139138
try (Scope s = tracer.withSpan(span)) {
140-
CommitResponse response =
141-
SpannerImpl.runWithRetries(
142-
new Callable<CommitResponse>() {
143-
@Override
144-
public CommitResponse call() throws Exception {
145-
return spanner.getRpc().commit(request, options);
146-
}
147-
});
139+
CommitResponse response = spanner.getRpc().commit(request, options);
148140
Timestamp t = Timestamp.fromProto(response.getCommitTimestamp());
149141
span.end();
150142
return t;
@@ -208,14 +200,7 @@ public void prepareReadWriteTransaction() {
208200
public void close() {
209201
Span span = tracer.spanBuilder(SpannerImpl.DELETE_SESSION).startSpan();
210202
try (Scope s = tracer.withSpan(span)) {
211-
SpannerImpl.runWithRetries(
212-
new Callable<Void>() {
213-
@Override
214-
public Void call() throws Exception {
215-
spanner.getRpc().deleteSession(name, options);
216-
return null;
217-
}
218-
});
203+
spanner.getRpc().deleteSession(name, options);
219204
span.end();
220205
} catch (RuntimeException e) {
221206
TraceUtil.endSpanWithFailure(span, e);
@@ -233,14 +218,7 @@ ByteString beginTransaction() {
233218
TransactionOptions.newBuilder()
234219
.setReadWrite(TransactionOptions.ReadWrite.getDefaultInstance()))
235220
.build();
236-
Transaction txn =
237-
SpannerImpl.runWithRetries(
238-
new Callable<Transaction>() {
239-
@Override
240-
public Transaction call() throws Exception {
241-
return spanner.getRpc().beginTransaction(request, options);
242-
}
243-
});
221+
Transaction txn = spanner.getRpc().beginTransaction(request, options);
244222
if (txn.getId().isEmpty()) {
245223
throw newSpannerException(ErrorCode.INTERNAL, "Missing id in transaction\n" + getName());
246224
}

0 commit comments

Comments
 (0)