[6.5.0] Add flag `experimental_throttle_remote_action_building` (#20861)

to allow users temporarily disable remote action building throttle.

Workaround for #20478.

Closes #20558.
Commit
https://github.com/bazelbuild/bazel/commit/294c904c30fe305f60e548a438940d5ab60a15b4

PiperOrigin-RevId: 597445193
Change-Id: Ib2c7133adf86139b35156d94e39cbf9e17906439

Co-authored-by: Chi Wang <chiwang@google.com>
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteExecutionService.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteExecutionService.java
index 94e6307..a672857 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteExecutionService.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteExecutionService.java
@@ -514,13 +514,29 @@
         : null;
   }
 
+  private void maybeAcquireRemoteActionBuildingSemaphore(ProfilerTask task)
+      throws InterruptedException {
+    if (!remoteOptions.throttleRemoteActionBuilding) {
+      return;
+    }
+
+    try (var c = Profiler.instance().profile(task, "acquiring semaphore")) {
+      remoteActionBuildingSemaphore.acquire();
+    }
+  }
+
+  private void maybeReleaseRemoteActionBuildingSemaphore() {
+    if (!remoteOptions.throttleRemoteActionBuilding) {
+      return;
+    }
+
+    remoteActionBuildingSemaphore.release();
+  }
+
   /** Creates a new {@link RemoteAction} instance from spawn. */
   public RemoteAction buildRemoteAction(Spawn spawn, SpawnExecutionContext context)
       throws IOException, ExecException, ForbiddenActionInputException, InterruptedException {
-    try (SilentCloseable c =
-        Profiler.instance().profile(ProfilerTask.REMOTE_SETUP, "acquiring semaphore")) {
-      remoteActionBuildingSemaphore.acquire();
-    }
+    maybeAcquireRemoteActionBuildingSemaphore(ProfilerTask.REMOTE_SETUP);
     try {
       ToolSignature toolSignature = getToolSignature(spawn, context);
       final MerkleTree merkleTree = buildInputMerkleTree(spawn, context, toolSignature);
@@ -573,7 +589,7 @@
           actionKey,
           remoteOptions.remoteDiscardMerkleTrees);
     } finally {
-      remoteActionBuildingSemaphore.release();
+      maybeReleaseRemoteActionBuildingSemaphore();
     }
   }
 
@@ -1463,10 +1479,7 @@
     // concurrency. This prevents memory exhaustion. We assume that
     // ensureInputsPresent() provides enough parallelism to saturate the
     // network connection.
-    try (SilentCloseable c =
-        Profiler.instance().profile(ProfilerTask.UPLOAD_TIME, "acquiring semaphore")) {
-      remoteActionBuildingSemaphore.acquire();
-    }
+    maybeAcquireRemoteActionBuildingSemaphore(ProfilerTask.UPLOAD_TIME);
     try {
       MerkleTree merkleTree = action.getMerkleTree();
       if (merkleTree == null) {
@@ -1486,7 +1499,7 @@
           additionalInputs,
           force);
     } finally {
-      remoteActionBuildingSemaphore.release();
+      maybeReleaseRemoteActionBuildingSemaphore();
     }
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/remote/options/RemoteOptions.java b/src/main/java/com/google/devtools/build/lib/remote/options/RemoteOptions.java
index 092d5ca..11e436b 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/options/RemoteOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/options/RemoteOptions.java
@@ -27,6 +27,7 @@
 import com.google.devtools.common.options.Converter;
 import com.google.devtools.common.options.Converters;
 import com.google.devtools.common.options.Converters.AssignmentConverter;
+import com.google.devtools.common.options.Converters.BooleanConverter;
 import com.google.devtools.common.options.EnumConverter;
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
@@ -732,6 +733,19 @@
               + " seconds.")
   public Duration remoteFailureWindowInterval;
 
+  @Option(
+      name = "experimental_throttle_remote_action_building",
+      defaultValue = "true",
+      converter = BooleanConverter.class,
+      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+      metadataTags = OptionMetadataTag.EXPERIMENTAL,
+      effectTags = {OptionEffectTag.EXECUTION},
+      help =
+          "Whether to throttle the building of remote action to avoid OOM. Defaults to true.\n\n"
+              + "This is a temporary flag to allow users switch off the behaviour. Once Bazel is"
+              + " smart enough about the RAM/CPU usages, this flag will be removed.")
+  public boolean throttleRemoteActionBuilding;
+
   // The below options are not configurable by users, only tests.
   // This is part of the effort to reduce the overall number of flags.