Move BuildEventServiceClient lifetime management in to the BuildEventServiceModule implementations, allowing them to cache connections to a backend across blaze invocations.
PiperOrigin-RevId: 227747738
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventservice/BUILD b/src/main/java/com/google/devtools/build/lib/buildeventservice/BUILD
index 5f3dad0..5b00d29 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventservice/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/buildeventservice/BUILD
@@ -36,6 +36,7 @@
"//src/main/java/com/google/devtools/build/lib/buildeventstream/transports",
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/common/options",
+ "//third_party:auto_value",
"//third_party:guava",
"//third_party:jsr305",
"//third_party/grpc:grpc-jar",
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModule.java b/src/main/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModule.java
index 2a85a38..1e2304b 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModule.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModule.java
@@ -14,12 +14,14 @@
package com.google.devtools.build.lib.buildeventservice;
+import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.authandtls.AuthAndTLSOptions;
import com.google.devtools.build.lib.authandtls.GoogleAuthUtils;
import com.google.devtools.build.lib.buildeventservice.client.BuildEventServiceClient;
import com.google.devtools.build.lib.buildeventservice.client.ManagedBuildEventServiceGrpcClient;
import java.io.IOException;
+import java.util.Objects;
import java.util.Set;
/**
@@ -28,17 +30,45 @@
public class BazelBuildEventServiceModule
extends BuildEventServiceModule<BuildEventServiceOptions> {
+ @AutoValue
+ abstract static class BackendConfig {
+ abstract String besBackend();
+
+ abstract AuthAndTLSOptions authAndTLSOptions();
+ }
+
+ private BuildEventServiceClient client;
+ private BackendConfig config;
+
@Override
protected Class<BuildEventServiceOptions> optionsClass() {
return BuildEventServiceOptions.class;
}
@Override
- protected BuildEventServiceClient createBesClient(BuildEventServiceOptions besOptions,
- AuthAndTLSOptions authAndTLSOptions) throws IOException {
- return new ManagedBuildEventServiceGrpcClient(
- GoogleAuthUtils.newChannel(besOptions.besBackend, authAndTLSOptions),
- GoogleAuthUtils.newCallCredentials(authAndTLSOptions));
+ protected BuildEventServiceClient getBesClient(
+ BuildEventServiceOptions besOptions, AuthAndTLSOptions authAndTLSOptions) throws IOException {
+ BackendConfig newConfig =
+ new AutoValue_BazelBuildEventServiceModule_BackendConfig(
+ besOptions.besBackend, authAndTLSOptions);
+ if (client == null || !Objects.equals(config, newConfig)) {
+ clearBesClient();
+ config = newConfig;
+ client =
+ new ManagedBuildEventServiceGrpcClient(
+ GoogleAuthUtils.newChannel(besOptions.besBackend, authAndTLSOptions),
+ GoogleAuthUtils.newCallCredentials(authAndTLSOptions));
+ }
+ return client;
+ }
+
+ @Override
+ protected void clearBesClient() {
+ if (client != null) {
+ client.shutdown();
+ }
+ this.client = null;
+ this.config = null;
}
private static final ImmutableSet<String> WHITELISTED_COMMANDS =
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceModule.java b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceModule.java
index f933670..4582d0e 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceModule.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceModule.java
@@ -63,6 +63,7 @@
private OutErr outErr;
private BuildEventStreamer streamer;
+ private boolean keepClient;
/** Whether an error in the Build Event Service upload causes the build to fail. */
protected boolean errorsShouldFailTheBuild() {
@@ -95,6 +96,7 @@
return;
}
+ this.keepClient = false;
streamer = tryCreateStreamer(commandEnvironment);
if (streamer != null) {
commandEnvironment.getReporter().addHandler(streamer);
@@ -137,6 +139,9 @@
@Override
public void afterCommand() {
+ if (!keepClient) {
+ clearBesClient();
+ }
this.outErr = null;
this.streamer = null;
}
@@ -156,9 +161,14 @@
env.getReporter(),
env.getBlazeModuleEnvironment(),
new AbruptExitException(message, ExitCode.PUBLISH_ERROR, e));
+ clearBesClient();
return null;
}
+ BuildEventStreamOptions buildEventStreamOptions =
+ env.getOptions().getOptions(BuildEventStreamOptions.class);
+ this.keepClient = buildEventStreamOptions.keepBackendConnections;
+
ImmutableSet<BuildEventTransport> bepTransports =
BuildEventTransportFactory.createFromOptions(env, env.getBlazeModuleEnvironment()::exit);
@@ -170,8 +180,6 @@
ImmutableSet<BuildEventTransport> transports = transportsBuilder.build();
if (!transports.isEmpty()) {
- BuildEventStreamOptions buildEventStreamOptions =
- env.getOptions().getOptions(BuildEventStreamOptions.class);
return new BuildEventStreamer(transports, env.getReporter(), buildEventStreamOptions);
}
} catch (Exception e) {
@@ -201,6 +209,7 @@
if (isNullOrEmpty(besOptions.besBackend)) {
logger.fine("BuildEventServiceTransport is disabled.");
+ clearBesClient();
return null;
} else {
logger.fine(
@@ -226,7 +235,7 @@
besOptions.besBackend, env.getBuildRequestId(), invocationId)));
}
- BuildEventServiceClient client = createBesClient(besOptions, authTlsOptions);
+ BuildEventServiceClient client = getBesClient(besOptions, authTlsOptions);
BuildEventArtifactUploader artifactUploader =
env.getRuntime()
.getBuildEventArtifactUploaderFactoryMap()
@@ -272,10 +281,12 @@
protected abstract Class<T> optionsClass();
- protected abstract BuildEventServiceClient createBesClient(
+ protected abstract BuildEventServiceClient getBesClient(
T besOptions, AuthAndTLSOptions authAndTLSOptions)
throws IOException, OptionsParsingException;
+ protected abstract void clearBesClient();
+
protected abstract Set<String> whitelistedCommands();
protected Set<String> keywords(
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceTransport.java b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceTransport.java
index 6fae0e2..4283043 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceTransport.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceTransport.java
@@ -423,11 +423,7 @@
logError(e, "BES upload failed due to a RuntimeException. This is a bug.");
throw e;
} finally {
- try {
- besClient.shutdown();
- } finally {
- localFileUploader.shutdown();
- }
+ localFileUploader.shutdown();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventStreamOptions.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventStreamOptions.java
index 9e0c277..4da6c78 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventStreamOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventStreamOptions.java
@@ -17,6 +17,7 @@
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
+import com.google.devtools.common.options.OptionMetadataTag;
import com.google.devtools.common.options.OptionsBase;
/** Options used to configure BuildEventStreamer and its BuildEventTransports. */
@@ -33,6 +34,15 @@
public String buildEventTextFile;
@Option(
+ name = "keep_backend_build_event_connections_alive",
+ defaultValue = "true",
+ metadataTags = {OptionMetadataTag.HIDDEN},
+ documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ help = "If enabled, keep connections to build event backend connections alive across builds.")
+ public boolean keepBackendConnections;
+
+ @Option(
name = "build_event_binary_file",
oldName = "experimental_build_event_binary_file",
defaultValue = "",