Skip to content

Commit

Permalink
Add profiler task for calling a credential helper.
Browse files Browse the repository at this point in the history
This might help debug future performance issues related caused by slow
credential helpers.

Closes bazelbuild#16226.

PiperOrigin-RevId: 472683449
Change-Id: Ib1f51a51763ccfa0e18be980fd4b4d77954a9814
  • Loading branch information
tjgq authored and Copybara-Service committed Sep 7, 2022
1 parent 93725da commit 9c0940d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 42 deletions.
Expand Up @@ -13,6 +13,7 @@ java_library(
srcs = glob(["*.java"]),
deps = [
"//src/main/java/com/google/devtools/build/lib/events",
"//src/main/java/com/google/devtools/build/lib/profiler",
"//src/main/java/com/google/devtools/build/lib/shell",
"//src/main/java/com/google/devtools/build/lib/vfs",
"//third_party:auth",
Expand Down
Expand Up @@ -14,12 +14,15 @@

package com.google.devtools.build.lib.authandtls.credentialhelper;

import static com.google.devtools.build.lib.profiler.ProfilerTask.CREDENTIAL_HELPER;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.io.CharStreams;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.SilentCloseable;
import com.google.devtools.build.lib.shell.Subprocess;
import com.google.devtools.build.lib.shell.SubprocessBuilder;
import com.google.devtools.build.lib.vfs.Path;
Expand Down Expand Up @@ -68,57 +71,62 @@ public GetCredentialsResponse getCredentials(CredentialHelperEnvironment environ
Preconditions.checkNotNull(environment);
Preconditions.checkNotNull(uri);

Subprocess process = spawnSubprocess(environment, "get");
try (Reader stdout = new InputStreamReader(process.getInputStream(), UTF_8);
Reader stderr = new InputStreamReader(process.getErrorStream(), UTF_8)) {
try (Writer stdin = new OutputStreamWriter(process.getOutputStream(), UTF_8)) {
GSON.toJson(GetCredentialsRequest.newBuilder().setUri(uri).build(), stdin);
}
Profiler prof = Profiler.instance();

process.waitFor();
if (process.timedout()) {
throw new CredentialHelperException(
String.format(
Locale.US,
"Failed to get credentials for '%s' from helper '%s': process timed out",
uri,
path));
}
if (process.exitValue() != 0) {
throw new CredentialHelperException(
String.format(
Locale.US,
"Failed to get credentials for '%s' from helper '%s': process exited with code %d."
+ " stderr: %s",
uri,
path,
process.exitValue(),
CharStreams.toString(stderr)));
}
try (SilentCloseable c = prof.profile(CREDENTIAL_HELPER, "calling credential helper")) {
Subprocess process = spawnSubprocess(environment, "get");
try (Reader stdout = new InputStreamReader(process.getInputStream(), UTF_8);
Reader stderr = new InputStreamReader(process.getErrorStream(), UTF_8)) {
try (Writer stdin = new OutputStreamWriter(process.getOutputStream(), UTF_8)) {
GSON.toJson(GetCredentialsRequest.newBuilder().setUri(uri).build(), stdin);
}

process.waitFor();

try {
GetCredentialsResponse response = GSON.fromJson(stdout, GetCredentialsResponse.class);
if (response == null) {
if (process.timedout()) {
throw new CredentialHelperException(
String.format(
Locale.US,
"Failed to get credentials for '%s' from helper '%s': process exited without"
+ " output. stderr: %s",
"Failed to get credentials for '%s' from helper '%s': process timed out",
uri,
path));
}
if (process.exitValue() != 0) {
throw new CredentialHelperException(
String.format(
Locale.US,
"Failed to get credentials for '%s' from helper '%s': process exited with code"
+ " %d. stderr: %s",
uri,
path,
process.exitValue(),
CharStreams.toString(stderr)));
}
return response;
} catch (JsonSyntaxException e) {
throw new CredentialHelperException(
String.format(
Locale.US,
"Failed to get credentials for '%s' from helper '%s': error parsing output. stderr:"
+ " %s",
uri,
path,
CharStreams.toString(stderr)),
e);

try {
GetCredentialsResponse response = GSON.fromJson(stdout, GetCredentialsResponse.class);
if (response == null) {
throw new CredentialHelperException(
String.format(
Locale.US,
"Failed to get credentials for '%s' from helper '%s': process exited without"
+ " output. stderr: %s",
uri,
path,
CharStreams.toString(stderr)));
}
return response;
} catch (JsonSyntaxException e) {
throw new CredentialHelperException(
String.format(
Locale.US,
"Failed to get credentials for '%s' from helper '%s': error parsing output."
+ " stderr: %s",
uri,
path,
CharStreams.toString(stderr)),
e);
}
}
}
}
Expand Down
Expand Up @@ -86,6 +86,7 @@ public enum ProfilerTask {
WORKER_BORROW("borrowing a worker"),
WORKER_WORKING("waiting for response from worker"),
WORKER_COPYING_OUTPUTS("copying outputs from worker"),
CREDENTIAL_HELPER("calling credential helper"),
UNKNOWN("Unknown event");

private static class Threshold {
Expand Down

0 comments on commit 9c0940d

Please sign in to comment.