Skip to content

Enable timeout propagation for remote actions #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

arvi18
Copy link

@arvi18 arvi18 commented Apr 28, 2025

When building using remote execution,
action timeouts sometimes need to be adjusted
per action to ensure reasonable timeouts are set.

This change will allow better control over how
actions behave and encourage users to
optimize their actions since the global default timeout does not have to be set to the absolute largest
action timeout in the graph.

Summary by CodeRabbit

  • New Features

    • Improved support for timeout tags in execution requirements, allowing for more flexible and validated timeout specifications.
    • Enhanced error reporting for duplicate or invalid timeout tags with specific failure codes.
  • Bug Fixes

    • More robust validation and canonical formatting for timeout values to prevent invalid entries.
  • Tests

    • Added and updated tests to verify correct handling and extraction of timeout tags in execution info.
  • Documentation

    • Updated failure codes to document new error cases for timeout tag handling.

When building using remote execution,
action timeouts sometimes need to be adjusted
per action to ensure reasonable timeouts are set.

This change will allow better control over how
actions behave and encourage users to
optimize their actions since the global default timeout
does not have to be set to the absolute largest
action timeout in the graph.

Change-Id: I0ea63787ff7769e25dd597575cbfd7fd1050797e
Timeout may either be specified as a tag on format
tags = ["tag:<int-seconds>"]
or as execution_requirements on any action on dict format
execution_requirements = {
   "timeout": "<int-seconds>"
}

Change-Id: Ida3bf173a291e7d949046bc4df3d1d4a02d8328d
@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

Hi @quic-sbjorkle,  Could you please sign the CLA.

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

Hi @quic-sbjorkle,  Could you please sign the CLA.

@sgowroji Should be signed now if you retrigger the check.

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

@tjgq Any ETA for when you can take a look at this? Thanks

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

@bazel-io flag

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

I'm supportive of this PR in principle, but I need to do some due diligence to verify that reinterpreting an existing timeout tag won't cause problems at Google.

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

@bazel-io fork 8.0.0

Copy link

coderabbitai bot commented Apr 28, 2025

Walkthrough

The changes introduce enhanced support for timeout specifications in execution requirements and spawn actions. The timeout requirement is now represented as a ParseableRequirement with strict validation and parsing logic. The logic for extracting and validating timeout values from execution info is refactored in the Spawns class, allowing for detection of duplicate or invalid timeout tags and providing improved error reporting. The set of legal execution info keys is expanded to include any prefix starting with "timeout". Two new error codes related to timeout tags are added to failure details. Associated tests are updated and expanded to cover the new behaviors.

Changes

Files/Paths Change Summary
src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java Changed TIMEOUT from a string constant to a ParseableRequirement with regex-based detection and validation for timeout tags.
src/main/java/com/google/devtools/build/lib/actions/Spawns.java Refactored getTimeout to support multiple timeout tags, improved error handling for duplicates/invalid tags, and extracted parsing/validation logic into helper methods.
src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java Changed the key used for timeout in executionInfo from the constant to the literal string "timeout".
src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java Modified legalExecInfoKeys to allow keys with the "timeout" prefix.
src/main/protobuf/failure_details.proto Added two new enum values to Spawn.Code: DUPLICATE_TIMEOUT_TAGS and INVALID_TIMEOUT_TAG, both with exit code 1.
src/test/java/com/google/devtools/build/lib/packages/TargetUtilsTest.java Added test for extracting execution info from tags with the "timeout:" prefix.
src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java Updated a test to remove the "timeout" key from execution requirements and added a new test verifying correct handling of the "timeout" key in execution info.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Spawn
    participant Spawns
    participant ExecutionRequirements

    User->>Spawn: Provide execution info (may include timeout tags)
    Spawn->>Spawns: Call getTimeout(executionInfo, defaultTimeout)
    Spawns->>ExecutionRequirements: Validate and parse timeout tags
    ExecutionRequirements-->>Spawns: Return validated timeout or error
    Spawns-->>User: Return timeout Duration or throw ExecException
Loading

Poem

In the warren of code, where time hops ahead,
A timeout tag now checks what’s said.
No more duplicates, no sneaky tags—
Only valid seconds in our execution bags!
With tests and enums, we’re ready for flight,
This bunny’s code changes are working just right.
🕒🐇

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.31.1)
src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

For triaging purposes -- is this fixing a regression introduced in an earlier 8.0.0 RC?

If not, this need not be release-blocking, but we can certainly cherry-pick to 8.1.0 at least.

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

@Wyverald It's a feature request, no need to hold up the release.

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

@tjgq Are there any more changes needed from my side, or is it good to go now?

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

Sorry, I'm about to be out of office, so I won't have time to look into this until January. I would also like @zhengwei143 to do a review of his own.

@arvi18
Copy link
Author

arvi18 commented Apr 28, 2025

@zhengwei143 @tjgq Friendly ping

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @arvi18, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

This pull request enables timeout propagation for remote actions. The goal is to allow better control over how actions behave and encourage users to optimize their actions, since the global default timeout does not have to be set to the absolute largest action timeout in the graph. This is achieved by allowing the timeout to be specified either as a tag or as a key-value pair in the execution requirements. The code changes modify how timeouts are parsed and validated, and add new failure detail codes for duplicate or invalid timeout tags.

Highlights

  • Timeout Propagation: The PR enables the propagation of timeouts for remote actions, allowing for more granular control over action timeouts.
  • Timeout Specification: Timeouts can now be specified either as a tag (timeout:) or as a key-value pair in the execution requirements.
  • Validation: The PR includes validation to ensure that timeout values are properly formatted and within acceptable ranges.
  • Error Handling: New failure detail codes have been added to handle cases where there are duplicate or invalid timeout tags.

Changelog

Click here to see the changelog
  • src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java
    • Introduces ParseableRequirement for timeout to allow validation and parsing of timeout values.
    • Adds validation logic to ensure timeout values are positive integers in canonical format.
  • src/main/java/com/google/devtools/build/lib/actions/Spawns.java
    • Modifies getTimeout to retrieve timeout values from either a 'timeout' key or a 'timeout:' tag in the execution info.
    • Adds error handling for multiple timeout values and invalid timeout tags, including new FailureDetail codes.
    • Introduces helper methods getTimeoutValueFromExecutionInfoKeyOrValue and parseTimeoutValue to handle timeout parsing and retrieval.
  • src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java
    • Updates the way the timeout is added to the execution info, using the key "timeout" instead of ExecutionRequirements.TIMEOUT.
  • src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java
    • Adds 'timeout' to the list of legal execution info keys.
  • src/main/protobuf/failure_details.proto
    • Adds new failure detail codes DUPLICATE_TIMEOUT_TAGS and INVALID_TIMEOUT_TAG.
  • src/test/java/com/google/devtools/build/lib/packages/TargetUtilsTest.java
    • Adds a test case testExecutionInfo_withPrefixTimeout to verify that timeout tags are correctly parsed.
  • src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java
    • Removes timeout from the default execution requirements in testCreateSpawnActionEnvAndExecInfo.
    • Adds a new test case testCreateSpawnActionEnvAndExecInfo_withTimeout to verify that timeout values are correctly passed to the SpawnAction.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


A timed action's plight,
Needs a timeout, day and night,
No longer wait,
Propagate,
And set things right.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces timeout propagation for remote actions, allowing for better control over action behavior and encouraging users to optimize their actions. The changes involve modifying the ExecutionRequirements class to use a ParseableRequirement for timeouts, updating Spawns to handle timeout values from execution info, and adjusting StandaloneTestStrategy and TargetUtils to accommodate the new timeout implementation. Overall, the changes seem well-structured and address the intended goal.

Summary of Findings

  • Timeout Value Parsing: The code introduces a new way to parse timeout values, allowing them to be specified either as a tag or as a key-value pair. It's important to ensure that this new parsing logic is robust and handles various edge cases, such as invalid timeout formats or multiple timeout values.
  • Error Handling: The code includes error handling for invalid timeout values and duplicate timeout tags. It's crucial to ensure that these error messages are clear and informative, providing users with actionable guidance on how to resolve the issues.
  • Code Duplication: The code introduces new methods for retrieving and parsing timeout values. Consider refactoring the code to reduce duplication and improve maintainability.

Merge Readiness

The pull request introduces important functionality for timeout propagation. While the changes appear to be well-structured, there are some areas that could benefit from further refinement, particularly in error handling and code duplication. I recommend addressing the review comments before merging. I am unable to directly approve this pull request, and other reviewers should also review this code before merging.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/main/java/com/google/devtools/build/lib/actions/Spawns.java (2)

158-176: Duplicate-tag scan can short-circuit after first hit

Once a valid timeout value is discovered you continue iterating over the remaining
executionInfo entries and only fail when a second timeout is met.
A quick break after setting timeout would:

  1. Avoid needless work on large tag maps.
  2. Prevent accidentally accepting an earlier malformed tag that appears after
    the first valid one (today it is silently ignored).
-            timeout = parseTimeoutValue(value);
+            timeout = parseTimeoutValue(value);
+            break; // first match wins – avoids O(n) scan & inconsistent state

165-168: Error message could include offending tags for easier debugging

When duplicate timeouts are detected, consider including the full set of
conflicting tags/keys encountered in the exception message so that users can
quickly locate and fix them.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0c98a2 and e22c7da.

📒 Files selected for processing (7)
  • src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java (1 hunks)
  • src/main/java/com/google/devtools/build/lib/actions/Spawns.java (2 hunks)
  • src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java (1 hunks)
  • src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java (1 hunks)
  • src/main/protobuf/failure_details.proto (1 hunks)
  • src/test/java/com/google/devtools/build/lib/packages/TargetUtilsTest.java (1 hunks)
  • src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/com/google/devtools/build/lib/actions/Spawns.java (1)
src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java (2)
  • ExecutionRequirements (40-335)
  • ValidationException (55-77)
🔇 Additional comments (7)
src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java (1)

121-145: Well-designed timeout validation implementation

The new ParseableRequirement for timeout correctly validates that:

  • The value is a parseable integer
  • The value is in canonical format (no leading zeros or plus signs)
  • The value is positive (greater than zero)
  • Provides clear error messages for each validation failure

This implementation aligns well with the PR's goal of improving timeout management by enabling per-action timeout propagation.

src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java (1)

53-64: Good addition for timeout tag support

Adding tag.startsWith("timeout") to legalExecInfoKeys properly enables propagation of timeout-related tags from targets to execution requirements.

This change complements the ExecutionRequirements refactoring and ensures that users can specify timeout tags that will be correctly propagated to spawned actions.

src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java (1)

122-122: Correctly updated timeout key usage

The change from ExecutionRequirements.TIMEOUT to the literal string "timeout" properly accommodates the refactoring of TIMEOUT from a string constant to a ParseableRequirement object, ensuring that the execution info map continues to work with the new implementation.

src/main/protobuf/failure_details.proto (1)

225-226: Good error handling for timeout issues

The new error codes DUPLICATE_TIMEOUT_TAGS and INVALID_TIMEOUT_TAG provide clear, specific failure reporting for timeout-related issues, improving the user experience when timeouts are misconfigured.

This complements the validation logic added to ExecutionRequirements and enables better error reporting when users specify invalid timeout values.

src/test/java/com/google/devtools/build/lib/packages/TargetUtilsTest.java (1)

226-237: Nice addition of test for timeout prefix.

The new test correctly verifies that execution info tags prefixed with timeout: are properly extracted into the execution info map. This test aligns well with the other prefix tests in the file and properly supports the enhanced timeout handling functionality.

src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java (2)

419-419: Appropriately removed timeout from combined test.

Good cleanup by removing the timeout key from this test's execution requirements. This makes sense since you've now created a dedicated test for timeout handling.


431-451: Good addition of dedicated timeout test.

This new test properly validates that the timeout execution requirement is correctly handled in spawn actions. Isolating the timeout test ensures clean validation of this specific feature and aligns with the PR's objective of enhancing timeout propagation for remote actions.

Comment on lines 213 to +221
try {
return Duration.ofSeconds(Integer.parseInt(timeoutStr));
return Duration.ofSeconds(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new UserExecException(
e,
FailureDetail.newBuilder()
.setMessage("could not parse timeout")
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT))
.build());
throw new UserExecException(
e,
FailureDetail.newBuilder()
.setMessage("could not parse timeout")
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT))
.build());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Negative or zero seconds still accepted – explicitly reject them

Duration.ofSeconds(Integer.parseInt(value)) will happily create negative or
zero durations. The validator above (tag path) already forbids those, so the
value-based path should be equally strict.

     try {
-        return Duration.ofSeconds(Integer.parseInt(value));
+        int seconds = Integer.parseInt(value);
+        if (seconds < 1) {
+          throw new UserExecException(
+              FailureDetail.newBuilder()
+                  .setMessage("timeout must be a positive integer")
+                  .setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT_TAG))
+                  .build());
+        }
+        return Duration.ofSeconds(seconds);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
return Duration.ofSeconds(Integer.parseInt(timeoutStr));
return Duration.ofSeconds(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new UserExecException(
e,
FailureDetail.newBuilder()
.setMessage("could not parse timeout")
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT))
.build());
throw new UserExecException(
e,
FailureDetail.newBuilder()
.setMessage("could not parse timeout")
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT))
.build());
try {
int seconds = Integer.parseInt(value);
if (seconds < 1) {
throw new UserExecException(
FailureDetail.newBuilder()
.setMessage("timeout must be a positive integer")
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT_TAG))
.build());
}
return Duration.ofSeconds(seconds);
} catch (NumberFormatException e) {
throw new UserExecException(
e,
FailureDetail.newBuilder()
.setMessage("could not parse timeout")
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT))
.build());
}

Comment on lines +189 to +205
if (entry.getKey().equals("timeout")) {
value = entry.getValue();
} else {
try {
value = requirement.parseIfMatches(entry.getKey());
} catch (ValidationException e) {
throw new UserExecException(
e,
FailureDetail.newBuilder()
.setMessage(
String.format(
"%s has a '%s' tag, but its value '%s' didn't pass validation: %s",
spawn.getTargetLabel(), requirement.userFriendlyName(), e.getTagValue(), e.getMessage()))
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT_TAG))
.build());
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Validation is inconsistent between timeout key and timeout:<int> tag

The "timeout" key path bypasses the ExecutionRequirements.TIMEOUT validator,
so values like "0", "-3", "+04" or " 5 " silently pass, even though the
same values are rejected when expressed as a tag (timeout:…).
This breaks the “canonical, positive integer” contract and can surface as
negative‐duration Durations later in the pipeline.

-    if (entry.getKey().equals("timeout")) {
-        value = entry.getValue();
+    if (entry.getKey().equals("timeout")) {
+        value = entry.getValue();
+        // Re-use the canonical validator for consistency.
+        String error = requirement.validator().apply(value);
+        if (error != null) {
+          throw new UserExecException(
+              FailureDetail.newBuilder()
+                  .setMessage(
+                      String.format(
+                          "%s has a 'timeout' key, but its value '%s' %s",
+                          spawn.getTargetLabel(), value, error))
+                  .setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT_TAG))
+                  .build());
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (entry.getKey().equals("timeout")) {
value = entry.getValue();
} else {
try {
value = requirement.parseIfMatches(entry.getKey());
} catch (ValidationException e) {
throw new UserExecException(
e,
FailureDetail.newBuilder()
.setMessage(
String.format(
"%s has a '%s' tag, but its value '%s' didn't pass validation: %s",
spawn.getTargetLabel(), requirement.userFriendlyName(), e.getTagValue(), e.getMessage()))
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT_TAG))
.build());
}
}
if (entry.getKey().equals("timeout")) {
value = entry.getValue();
// Re-use the canonical validator for consistency.
String error = requirement.validator().apply(value);
if (error != null) {
throw new UserExecException(
FailureDetail.newBuilder()
.setMessage(
String.format(
"%s has a 'timeout' key, but its value '%s' %s",
spawn.getTargetLabel(), value, error))
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT_TAG))
.build());
}
} else {
try {
value = requirement.parseIfMatches(entry.getKey());
} catch (ValidationException e) {
throw new UserExecException(
e,
FailureDetail.newBuilder()
.setMessage(
String.format(
"%s has a '%s' tag, but its value '%s' didn't pass validation: %s",
spawn.getTargetLabel(),
requirement.userFriendlyName(),
e.getTagValue(),
e.getMessage()))
.setSpawn(FailureDetails.Spawn.newBuilder().setCode(Code.INVALID_TIMEOUT_TAG))
.build());
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants