// Copyright 2017 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.lib.actions; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.shell.TerminationStatus; import java.time.Duration; import java.util.Locale; import java.util.Optional; import javax.annotation.Nullable; /** * The result of a spawn execution. * *
DO NOT IMPLEMENT THIS INTERFACE! Use {@link SpawnResult.Builder} to create instances instead. * This is a temporary situation as long as we still have separate internal and external * implementations - the plan is to merge the two into a single immutable, final class. */ // TODO(ulfjack): Change this from an interface to an immutable, final class. public interface SpawnResult { /** The status of the attempted Spawn execution. */ public enum Status { /** Subprocess executed successfully, and returned a zero exit code. */ SUCCESS(true), /** Subprocess executed successfully, but returned a non-zero exit code. */ NON_ZERO_EXIT(true), /** Subprocess execution timed out. */ TIMEOUT(true), /** * The subprocess ran out of memory. On Linux systems, the kernel may kill processes in * low-memory situations, and this status is intended to report such a case back to Bazel. */ OUT_OF_MEMORY(true), /** * Subprocess did not execute. This error is not catastrophic - Bazel will try to continue the * build if keep_going is enabled, possibly attempt to rerun the same spawn, and attempt to run * other actions. */ EXECUTION_FAILED, /** * Subprocess did not execute. Do not retry, and exit immediately even if keep_going is enabled. */ EXECUTION_FAILED_CATASTROPHICALLY, /** * Subprocess did not execute in a way that indicates that the user can fix it. For example, a * remote system may have denied the execution due to too many inputs or too large inputs. */ EXECUTION_DENIED(true), /** * The remote execution system is overloaded and had to refuse execution for this Spawn. */ REMOTE_EXECUTOR_OVERLOADED, /** * The result of the remotely executed Spawn could not be retrieved due to errors in the remote * caching layer. */ REMOTE_CACHE_FAILED; private final boolean isUserError; private Status(boolean isUserError) { this.isUserError = isUserError; } private Status() { this(false); } public boolean isConsideredUserError() { return isUserError; } } /** * Returns whether the spawn was actually run, regardless of the exit code. I.e., returns * {@code true} if {@link #status} is any of {@link Status#SUCCESS}, {@link Status#NON_ZERO_EXIT}, * {@link Status#TIMEOUT} or {@link Status#OUT_OF_MEMORY}. * *
Returns false if there were errors that prevented the spawn from being run, such as network * errors, missing local files, errors setting up sandboxing, etc. */ boolean setupSuccess(); /** Returns true if the status was {@link Status#EXECUTION_FAILED_CATASTROPHICALLY}. */ boolean isCatastrophe(); /** The status of the attempted Spawn execution. */ Status status(); /** * The exit code of the subprocess if the subprocess was executed. Should only be called if * {@link #status} returns {@link Status#SUCCESS} or {@link Status#NON_ZERO_EXIT}. * *
This method must return a non-zero exit code if the status is {@link Status#TIMEOUT} or * {@link Status#OUT_OF_MEMORY}. It is recommended to return 128 + 14 when the status is * {@link Status#TIMEOUT}, which corresponds to the Unix signal SIGALRM. * *
This method may throw {@link IllegalStateException} if called for any other status.
*/
int exitCode();
/**
* The host name of the executor or {@code null}. This information is intended for debugging
* purposes, especially for remote execution systems. Remote caches usually do not store the
* original host name, so this is generally {@code null} for cache hits.
*/
@Nullable String getExecutorHostName();
/**
* Returns the wall time taken by the {@link Spawn}'s execution.
*
* @return the measurement, or empty in case of execution errors or when the measurement is not
* implemented for the current platform
*/
Optional