Skip to content

Commit 71b0525

Browse files
authored
feat: use LazySpannerInitializer instead of DCL (GoogleCloudPlatform#4197)
The Spanner client library now includes a lazy initializer for Spanner instances that can be used with Google Cloud Functions and other libraries that want to create an instance the first time one is needed and reuse this instance for subsequent requests. Fixes GoogleCloudPlatform#2862
1 parent 4168d32 commit 71b0525

1 file changed

Lines changed: 16 additions & 51 deletions

File tree

functions/spanner/src/main/java/functions/HelloSpanner.java

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
import com.google.cloud.functions.HttpResponse;
2424
import com.google.cloud.spanner.DatabaseClient;
2525
import com.google.cloud.spanner.DatabaseId;
26+
import com.google.cloud.spanner.LazySpannerInitializer;
2627
import com.google.cloud.spanner.ResultSet;
27-
import com.google.cloud.spanner.Spanner;
2828
import com.google.cloud.spanner.SpannerException;
2929
import com.google.cloud.spanner.SpannerOptions;
3030
import com.google.cloud.spanner.Statement;
@@ -38,63 +38,28 @@
3838
public class HelloSpanner implements HttpFunction {
3939
private static final Logger logger = Logger.getLogger(HelloSpanner.class.getName());
4040

41-
@VisibleForTesting
42-
static Spanner createSpanner() {
43-
return SpannerOptions.newBuilder().build().getService();
44-
}
45-
46-
// SpannerHolder is a holder class for a Spanner instance that is initialized lazily.
47-
private static final class SpannerHolder {
48-
private final Object lock = new Object();
49-
private volatile boolean initialized;
50-
private volatile DatabaseClient client;
51-
private volatile Throwable error;
52-
53-
private SpannerHolder() {}
41+
// TODO<developer>: Set these environment variables.
42+
private static final String SPANNER_INSTANCE_ID =
43+
MoreObjects.firstNonNull(System.getenv("SPANNER_INSTANCE"), "my-instance");
44+
private static final String SPANNER_DATABASE_ID =
45+
MoreObjects.firstNonNull(System.getenv("SPANNER_DATABASE"), "example-db");
5446

55-
// Initialize the {@link Spanner} instance in a method and not as a static variable, as it
56-
// might throw an error, and we want to catch and log that specific error. An administrator must
57-
// take action to mitigate the reason for the initialization failure, for example ensuring that
58-
// the service account being used to access Cloud Spanner has permission to do so.
59-
DatabaseClient get() throws Throwable {
60-
if (!initialized) {
61-
synchronized (lock) {
62-
if (!initialized) {
63-
try {
64-
DatabaseId db =
65-
DatabaseId.of(
66-
SpannerOptions.getDefaultProjectId(),
67-
SPANNER_INSTANCE_ID,
68-
SPANNER_DATABASE_ID);
69-
client = createSpanner().getDatabaseClient(db);
70-
} catch (Throwable t) {
71-
error = t;
72-
}
73-
initialized = true;
74-
}
75-
}
76-
}
77-
if (error != null) {
78-
throw error;
79-
}
80-
return client;
81-
}
82-
}
47+
private static final DatabaseId databaseId =
48+
DatabaseId.of(
49+
SpannerOptions.getDefaultProjectId(),
50+
SPANNER_INSTANCE_ID,
51+
SPANNER_DATABASE_ID);
8352

84-
// The SpannerHolder instance is shared across all instances of the HelloSpanner class.
85-
private static final SpannerHolder SPANNER_HOLDER = new SpannerHolder();
53+
// The LazySpannerInitializer instance is shared across all instances of the HelloSpanner class.
54+
// It will create a Spanner instance the first time one is requested, and continue to return that
55+
// instance for all subsequent requests.
56+
private static final LazySpannerInitializer SPANNER_INITIALIZER = new LazySpannerInitializer();
8657

8758
@VisibleForTesting
8859
DatabaseClient getClient() throws Throwable {
89-
return SPANNER_HOLDER.get();
60+
return SPANNER_INITIALIZER.get().getDatabaseClient(databaseId);
9061
}
9162

92-
// TODO<developer>: Set these environment variables.
93-
private static final String SPANNER_INSTANCE_ID =
94-
MoreObjects.firstNonNull(System.getenv("SPANNER_INSTANCE"), "my-instance");
95-
private static final String SPANNER_DATABASE_ID =
96-
MoreObjects.firstNonNull(System.getenv("SPANNER_DATABASE"), "example-db");
97-
9863
@Override
9964
public void service(HttpRequest request, HttpResponse response) throws Exception {
10065
var writer = new PrintWriter(response.getWriter());

0 commit comments

Comments
 (0)