diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java index 0a2661fde95dc7..56de39965b24f1 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java @@ -340,10 +340,27 @@ public void beforeCommand(CommandEnvironment env) throws AbruptExitException { starlarkRepositoryFunction.setWorkerExecutorService(repoFetchingWorkerThreadPool); break; case VIRTUAL: - throw new AbruptExitException( - detailedExitCode( - "using a virtual worker thread for repo fetching is not yet supported", - Code.BAD_DOWNLOADER_CONFIG)); + case AUTO: + try { + // Since Google hasn't migrated to JDK 21 yet, we can't directly call + // Executors.newVirtualThreadPerTaskExecutor here. But a bit of reflection never hurt + // anyone... right? (OSS Bazel already ships with a bundled JDK 21) + starlarkRepositoryFunction.setWorkerExecutorService( + (ExecutorService) + Executors.class + .getDeclaredMethod("newVirtualThreadPerTaskExecutor") + .invoke(null)); + } catch (ReflectiveOperationException e) { + if (repoOptions.workerForRepoFetching == RepositoryOptions.WorkerForRepoFetching.AUTO) { + starlarkRepositoryFunction.setWorkerExecutorService(null); + } else { + throw new AbruptExitException( + detailedExitCode( + "couldn't create virtual worker thread executor for repo fetching", + Code.BAD_DOWNLOADER_CONFIG), + e); + } + } } downloadManager.setDisableDownload(repoOptions.disableDownload); if (repoOptions.repositoryDownloaderRetries >= 0) { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java index e984bad9e35c94..e2183ed3957ad4 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java @@ -216,7 +216,8 @@ public class RepositoryOptions extends OptionsBase { public enum WorkerForRepoFetching { OFF, PLATFORM, - VIRTUAL; + VIRTUAL, + AUTO; static class Converter extends EnumConverter { public Converter() { @@ -227,14 +228,16 @@ public Converter() { @Option( name = "experimental_worker_for_repo_fetching", - defaultValue = "off", + defaultValue = "auto", converter = WorkerForRepoFetching.Converter.class, documentationCategory = OptionDocumentationCategory.REMOTE, effectTags = {OptionEffectTag.UNKNOWN}, help = "The threading mode to use for repo fetching. If set to 'off', no worker thread is used," + " and the repo fetching is subject to restarts. Otherwise, uses a platform thread" - + " (i.e. OS thread) if set to 'platform' or a virtual thread if set to 'virtual'.") + + " (i.e. OS thread) if set to 'platform' or a virtual thread if set to 'virtual'. If" + + " set to 'auto', virtual threads are used if available (i.e. running on JDK 21+)," + + " otherwise no worker thread is used.") public WorkerForRepoFetching workerForRepoFetching; @Option( diff --git a/src/test/shell/bazel/bazel_workspaces_test.sh b/src/test/shell/bazel/bazel_workspaces_test.sh index e65a60377e8aa6..b600f6a3eb8337 100755 --- a/src/test/shell/bazel/bazel_workspaces_test.sh +++ b/src/test/shell/bazel/bazel_workspaces_test.sh @@ -96,54 +96,6 @@ function test_execute() { ensure_contains_exactly "location: .*repos.bzl:2:25" 0 } -# The workspace is set up so that the function is interrupted and re-executed. -# The log should contain both instances. -function test_reexecute() { - create_new_workspace - cat > BUILD <<'EOF' -genrule( - name="test", - srcs=["@repo//:t.txt"], - outs=["out.txt"], - cmd="echo Result > $(location out.txt)" -) -EOF - cat >> repos.bzl <> WORKSPACE <& $TEST_log \ || fail "Expected build to succeed" expect_log_n "hello world!" 1 + + # virtual worker thread, never restarts + bazel shutdown + bazel build @foo//:bar --experimental_worker_for_repo_fetching=virtual >& $TEST_log \ + || fail "Expected build to succeed" + expect_log_n "hello world!" 1 } function test_duplicate_value_in_environ() {