Skip to content

Commit a1499c6

Browse files
committed
fix: reuse clientId for invalidated databases
1 parent 2d19c25 commit a1499c6

File tree

3 files changed

+23
-11
lines changed

3 files changed

+23
-11
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,10 +1704,9 @@ private void handleCreateSessionsFailure(SpannerException e, int count) {
17041704
break;
17051705
}
17061706
}
1707-
this.resourceNotFoundException =
1708-
MoreObjects.firstNonNull(
1709-
this.resourceNotFoundException,
1710-
isDatabaseOrInstanceNotFound(e) ? (ResourceNotFoundException) e : null);
1707+
if (isDatabaseOrInstanceNotFound(e)) {
1708+
setResourceNotFoundException((ResourceNotFoundException) e);
1709+
}
17111710
}
17121711
}
17131712

@@ -1734,9 +1733,7 @@ private void handlePrepareSessionFailure(
17341733
decrementPendingClosures(1);
17351734
}
17361735
allSessions.remove(session);
1737-
this.resourceNotFoundException =
1738-
MoreObjects.firstNonNull(
1739-
this.resourceNotFoundException, (ResourceNotFoundException) e);
1736+
setResourceNotFoundException((ResourceNotFoundException) e);
17401737
} else {
17411738
releaseSession(session, Position.FIRST);
17421739
}
@@ -1749,6 +1746,10 @@ private void handlePrepareSessionFailure(
17491746
}
17501747
}
17511748

1749+
void setResourceNotFoundException(ResourceNotFoundException e) {
1750+
this.resourceNotFoundException = MoreObjects.firstNonNull(this.resourceNotFoundException, e);
1751+
}
1752+
17521753
private void decrementPendingClosures(int count) {
17531754
pendingClosure -= count;
17541755
if (pendingClosure == 0) {

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,16 +162,20 @@ public InstanceAdminClient getInstanceAdminClient() {
162162
public DatabaseClient getDatabaseClient(DatabaseId db) {
163163
synchronized (this) {
164164
Preconditions.checkState(!spannerIsClosed, "Cloud Spanner client has been closed");
165+
String clientId = null;
165166
if (dbClients.containsKey(db) && !dbClients.get(db).pool.isValid()) {
166167
// Move the invalidated client to a separate list, so we can close it together with the
167168
// other database clients when the Spanner instance is closed.
168169
invalidatedDbClients.add(dbClients.get(db));
170+
clientId = dbClients.get(db).clientId;
169171
dbClients.remove(db);
170172
}
171173
if (dbClients.containsKey(db)) {
172174
return dbClients.get(db);
173175
} else {
174-
String clientId = nextDatabaseClientId(db);
176+
if (clientId == null) {
177+
clientId = nextDatabaseClientId(db);
178+
}
175179
List<LabelValue> labelValues =
176180
ImmutableList.of(
177181
LabelValue.create(clientId),

google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.google.cloud.NoCredentials;
2828
import com.google.cloud.ServiceRpc;
2929
import com.google.cloud.grpc.GrpcTransportOptions;
30+
import com.google.cloud.spanner.SpannerException.DoNotConstructDirectly;
3031
import com.google.cloud.spanner.spi.v1.SpannerRpc;
3132
import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions;
3233
import java.util.Collections;
@@ -187,7 +188,7 @@ public void testSpannerClosed() throws InterruptedException {
187188
}
188189

189190
@Test
190-
public void testClientId() {
191+
public void testClientId() throws Exception {
191192
// Create a unique database id to be sure it has not yet been used in the lifetime of this JVM.
192193
String dbName =
193194
String.format("projects/p1/instances/i1/databases/%s", UUID.randomUUID().toString());
@@ -212,6 +213,13 @@ public void testClientId() {
212213
DatabaseClientImpl databaseClient2 = (DatabaseClientImpl) impl.getDatabaseClient(db2);
213214
assertThat(databaseClient2.clientId).isEqualTo("client-1");
214215

216+
// Getting a new database client for an invalidated database should use the same client id.
217+
databaseClient.pool.setResourceNotFoundException(
218+
new DatabaseNotFoundException(DoNotConstructDirectly.ALLOWED, "not found", null, null));
219+
DatabaseClientImpl revalidated = (DatabaseClientImpl) impl.getDatabaseClient(db);
220+
assertThat(revalidated).isNotSameInstanceAs(databaseClient);
221+
assertThat(revalidated.clientId).isEqualTo(databaseClient.clientId);
222+
215223
// Create a new Spanner instance. This will generate new database clients with new ids.
216224
try (Spanner spanner =
217225
SpannerOptions.newBuilder()
@@ -222,8 +230,7 @@ public void testClientId() {
222230

223231
// Get a database client for the same database as the first database. As this goes through a
224232
// different Spanner instance with potentially different options, it will get a different
225-
// client
226-
// id.
233+
// client id.
227234
DatabaseClientImpl databaseClient3 = (DatabaseClientImpl) spanner.getDatabaseClient(db);
228235
assertThat(databaseClient3.clientId).isEqualTo("client-2");
229236
}

0 commit comments

Comments
 (0)