diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD index 1d5e560b921c7d..31ed023aeb27c7 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD @@ -82,6 +82,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/events", "//src/main/java/com/google/devtools/build/lib/util:os", "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", + "//third_party:caffeine", "//third_party:gson", "//third_party:guava", ], diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistry.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistry.java index 2d7945f95f6eac..9e88a988f2602e 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistry.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistry.java @@ -49,6 +49,7 @@ public class IndexRegistry implements Registry { private final DownloadManager downloadManager; private final Map clientEnv; private final Gson gson; + private volatile Optional bazelRegistryJson; public IndexRegistry(URI uri, DownloadManager downloadManager, Map clientEnv) { this.uri = uri; @@ -140,9 +141,6 @@ private Optional grabJson(String url, Class klass, ExtendedEventHandle public RepoSpec getRepoSpec( ModuleKey key, RepositoryName repoName, ExtendedEventHandler eventHandler) throws IOException, InterruptedException { - Optional bazelRegistryJson = - grabJson( - constructUrl(getUrl(), "bazel_registry.json"), BazelRegistryJson.class, eventHandler); Optional sourceJson = grabJson( constructUrl( @@ -157,14 +155,32 @@ public RepoSpec getRepoSpec( String type = sourceJson.get().type; switch (type) { case "archive": - return createArchiveRepoSpec(sourceJson, bazelRegistryJson, key, repoName); + return createArchiveRepoSpec(sourceJson, getBazelRegistryJson(eventHandler), key, repoName); case "local_path": - return createLocalPathRepoSpec(sourceJson, bazelRegistryJson, key, repoName); + return createLocalPathRepoSpec( + sourceJson, getBazelRegistryJson(eventHandler), key, repoName); default: throw new IOException(String.format("Invalid source type for module %s", key)); } } + @SuppressWarnings("OptionalAssignedToNull") + private Optional getBazelRegistryJson(ExtendedEventHandler eventHandler) + throws IOException, InterruptedException { + if (bazelRegistryJson == null) { + synchronized (this) { + if (bazelRegistryJson == null) { + bazelRegistryJson = + grabJson( + constructUrl(getUrl(), "bazel_registry.json"), + BazelRegistryJson.class, + eventHandler); + } + } + } + return bazelRegistryJson; + } + private RepoSpec createLocalPathRepoSpec( Optional sourceJson, Optional bazelRegistryJson, diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/RegistryFactoryImpl.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/RegistryFactoryImpl.java index 14df7054d4c0f4..8cab9b8cc5f9ef 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/RegistryFactoryImpl.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/RegistryFactoryImpl.java @@ -15,6 +15,8 @@ package com.google.devtools.build.lib.bazel.bzlmod; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import com.google.devtools.build.lib.bazel.repository.downloader.DownloadManager; import java.net.URI; import java.net.URISyntaxException; @@ -25,6 +27,7 @@ public class RegistryFactoryImpl implements RegistryFactory { private final DownloadManager downloadManager; private final Supplier> clientEnvironmentSupplier; + private final Cache registries = Caffeine.newBuilder().build(); public RegistryFactoryImpl( DownloadManager downloadManager, Supplier> clientEnvironmentSupplier) { @@ -43,7 +46,9 @@ public Registry getRegistryWithUrl(String url) throws URISyntaxException { case "http": case "https": case "file": - return new IndexRegistry(uri, downloadManager, clientEnvironmentSupplier.get()); + return registries.get( + url, + unused -> new IndexRegistry(uri, downloadManager, clientEnvironmentSupplier.get())); default: throw new URISyntaxException(uri.toString(), "Unrecognized registry URL protocol"); }