-
Notifications
You must be signed in to change notification settings - Fork 0
turbine support worker mode #23
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
base: master
Are you sure you want to change the base?
Conversation
Are you sure Turbine is ready for multiplexing? Is it thread-safe enough? Also, while that speedup is nice, timing a single action is not exactly statistically significant. |
There's some related discussion in bazelbuild#8006 The approach we took internally for turbine is to use a GraalVM native-image to improve cold-start performance, instead of using workers. I'd consider starting with that approach for Bazel if we invest in this area.
I think it probably is, FWIW. There isn't any shared mutable state. If there are thread-safety issues with turbine that prevent multiplexing, I'd be interested in trying to fix them. |
Related bazelbuild#16186 |
FWIW this is my 2c based on my experience using turbine at Google, I also don't have objections to Bazel supporting this as an option. |
@cushon how to publish java_tools, are there any guide for it? |
I don't think it is written anywhere but I would assume building |
Is it for temporary use only? How to modify |
After bazelbuild@3029a7d Assuming you just want to test bazel + custom turbine in some project, you can build a zip of custom |
WalkthroughThis change introduces multiplex worker support for the Java header compiler in the build system. It does so by adding a new wrapper class, Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant BuildSystem
participant TurbineWorkerWrapper
participant TurbineMain
User->>BuildSystem: Start Java header compilation
BuildSystem->>TurbineWorkerWrapper: Launch with --persistent_worker (if supported)
alt Persistent Worker Mode
TurbineWorkerWrapper->>BuildSystem: Wait for work requests
BuildSystem->>TurbineWorkerWrapper: Send work request
TurbineWorkerWrapper->>TurbineMain: Call compile(args)
TurbineMain-->>TurbineWorkerWrapper: Return result
TurbineWorkerWrapper->>BuildSystem: Send response
loop For each work request
BuildSystem->>TurbineWorkerWrapper: Send work request
TurbineWorkerWrapper->>TurbineMain: Call compile(args)
TurbineMain-->>TurbineWorkerWrapper: Return result
TurbineWorkerWrapper->>BuildSystem: Send response
end
else Direct Mode
TurbineWorkerWrapper->>TurbineMain: Delegate to Main.main(args)
end
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@cushon I have added the flag and the default value is false. |
There was a problem hiding this 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 introduces a wrapper to support Turbine in worker mode. It modifies the BUILD
file to change the main class to TurbineWorkerWrapper
and adds necessary dependencies. A new Java file, TurbineWorkerWrapper.java
, is created to handle the worker mode logic. Additionally, the JavaHeaderCompileAction.java
file is updated to use ParamFileInfo
with setUseAlways(true)
and to include worker mode execution requirements. The JavaToolchain
and JavaToolchainProvider
are updated to include header compiler support for workers and multiplex workers, and the JavaToolchainRule
is updated to include attributes for header compiler worker support.
Highlights
- Turbine Worker Wrapper: Implements a
TurbineWorkerWrapper
class to enable Turbine to run in worker mode, allowing persistent and multiplexed processing. - BUILD File Modification: Updates the
BUILD
file to use the newTurbineWorkerWrapper
as the main class and includes dependencies for worker mode support. - Execution Info Update: Modifies
JavaHeaderCompileAction
to add execution requirements for worker and multiplex worker modes based on the Java toolchain configuration. - Java Toolchain Updates: Extends
JavaToolchain
andJavaToolchainProvider
to include attributes indicating whether the header compiler supports worker and multiplex worker modes.
Changelog
Click here to see the changelog
- src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/BUILD
- Changed
main_class
toTurbineWorkerWrapper
. - Added
srcs
forTurbineWorkerWrapper.java
. - Added dependencies for worker mode support.
- Removed
//third_party:turbine
from runtime dependencies and added it to deps.
- Changed
- src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineWorkerWrapper.java
- Created a new class
TurbineWorkerWrapper
to handle Turbine in worker mode. - Implements the
main
method to process requests in persistent worker mode or delegate toMain.main
. - Includes logic to compile using Turbine via
Main.compile
.
- Created a new class
- src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java
- Updated
PARAM_FILE_INFO
to usesetUseAlways(true)
for parameter file usage (line 135). - Modified execution info to include worker mode and multiplex worker mode requirements based on toolchain support (lines 461-464).
- Updated the
tools
parameter in theJavaHeaderCompileAction
constructor to useheaderCompiler.tool().getFilesToRun()
(line 495).
- Updated
- src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
- Added attributes to store whether the header compiler supports workers and multiplex workers (lines 71-74).
- Passed the new attributes to the
JavaToolchainProvider
constructor (lines 175-176).
- src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java
- Added fields for
headerCompilerSupportsWorkers
andheaderCompilerSupportsMultiplexWorkers
(lines 100-101, 154-155, 189-190, 224-225, 258-259). - Updated the constructor and create methods to include these new fields.
- Added getter methods for
getHeaderCompilerSupportsWorkers
andgetHeaderCompilerSupportsMultiplexWorkers
(lines 433-438).
- Added fields for
- src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java
- Added attributes
header_compiler_supports_workers
andheader_compiler_supports_multiplex_workers
to the Java toolchain rule (lines 132-139).
- Added attributes
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 worker's task, defined with care,
To build and compile, beyond compare.
With Turbine's might,
It works day and night,
To keep our Java code so rare.
Footnotes
-
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. ↩
There was a problem hiding this 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 worker mode support for Turbine, which is a valuable performance optimization. The changes are well-structured and cover the necessary modifications in the build files, the Turbine wrapper, and the Java toolchain. However, there are a few areas that could be improved, particularly around error handling and default configurations.
Summary of Findings
- Missing tools dependency: The
JavaHeaderCompileAction
is missing thetools
dependency, which could lead to issues when running the header compiler in worker mode. The tool needs to be added to the action registration. - Inconsistent worker mode support: The code adds support for worker mode and multiplex worker mode for the header compiler, but the
JavaToolchainRule
defaults these tofalse
. This inconsistency should be addressed to enable worker mode by default. - Potential IOException handling: The
TurbineWorkerWrapper
catchesIOException
but only prints the message torealStdErr
. Consider logging the full stack trace for better debugging.
Merge Readiness
The pull request is not quite ready for merging. The tools
dependency issue in JavaHeaderCompileAction
is a high
severity issue that needs to be addressed to ensure the header compiler functions correctly in worker mode. The inconsistent worker mode support in JavaToolchainRule
should also be addressed. I am unable to approve this pull request, and recommend that another reviewer also look at this code before merging. I recommend that this pull request not be merged until the high severity issues are addressed.
.add(attr("header_compiler_supports_workers", BOOLEAN).value(false)) | ||
/* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(header_compiler_supports_multiplex_workers) --> | ||
True if JavaHeaderCompiler supports running as a multiplex persistent worker, false if it doesn't. | ||
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */ | ||
.add(attr("header_compiler_supports_multiplex_workers", BOOLEAN).value(false)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider setting the default value of header_compiler_supports_workers
and header_compiler_supports_multiplex_workers
to True
to enable worker mode by default, if it's stable and recommended.
.add(attr("header_compiler_supports_workers", BOOLEAN).value(false)) | |
/* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(header_compiler_supports_multiplex_workers) --> | |
True if JavaHeaderCompiler supports running as a multiplex persistent worker, false if it doesn't. | |
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */ | |
.add(attr("header_compiler_supports_multiplex_workers", BOOLEAN).value(false)) | |
.add(attr("header_compiler_supports_workers", BOOLEAN).value(True)) | |
/* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(header_compiler_supports_multiplex_workers) --> | |
True if JavaHeaderCompiler supports running as a multiplex persistent worker, false if it doesn't. | |
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */ | |
.add(attr("header_compiler_supports_multiplex_workers", BOOLEAN).value(True)) |
workerHandler.processRequests(); | ||
exitCode = 0; | ||
} catch (IOException e) { | ||
realStdErr.println(e.getMessage()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java (1)
132-139
: Default values still diverge fromjavac_*
flags – consider enabling by defaultBoth
javac_supports_workers
andjavac_supports_multiplex_workers
default totrue
, whereas the two new Turbine-specific flags default tofalse
. If Turbine is now proven stable in worker/multiplex mode, shipping the same defaults keeps the behaviour uniform and avoids requiring every user-definedjava_toolchain
to repeatheader_compiler_supports_workers = True
.
(Identical feedback was given previously.)src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineWorkerWrapper.java (1)
34-35
: Add stack trace printing for better debugging.Only printing the exception message may make debugging difficult. Consider adding stack trace printing to provide more context for troubleshooting.
realStdErr.println(e.getMessage()); +e.printStackTrace(realStdErr);
🧹 Nitpick comments (3)
src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineWorkerWrapper.java (3)
13-16
: Consider enhancing the class documentation.The current documentation is brief. Consider adding more details about how this wrapper enables multiplex worker mode and its benefits.
/** - * A Wrapper for Turbine to support multiplex worker + * A Wrapper for Turbine to support multiplex worker mode. This enables Turbine to run + * as a persistent worker that can process multiple compilation requests without + * restarting the JVM, significantly improving build performance for Java targets. */
45-53
: Add more specific exception handling and documentation.The catch block uses
Throwable
which is very broad. Consider adding documentation explaining this design choice or using more specific exception types if appropriate.private static int turbine(List<String> args, PrintWriter pw) { try { Main.compile(args.toArray(new String[0])); } catch (Throwable e) { + // Catch all exceptions to prevent worker crashes and allow processing subsequent requests pw.println(e.getMessage()); + e.printStackTrace(pw); return 1; } return 0; }
48-50
: Print the full stack trace for better error reporting.For better debugging, print the full stack trace of exceptions that occur during compilation.
} catch (Throwable e) { pw.println(e.getMessage()); + e.printStackTrace(pw); return 1; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/BUILD
(1 hunks)src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineWorkerWrapper.java
(1 hunks)src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java
(3 hunks)src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
(2 hunks)src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java
(6 hunks)src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineWorkerWrapper.java (1)
src/main/java/com/google/devtools/build/lib/worker/WorkRequestHandler.java (1)
WorkRequestHandler
(48-767)
🔇 Additional comments (11)
src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java (1)
71-75
: Guard against attribute absence to preserve backwards compatibility
header_compiler_supports_workers
andheader_compiler_supports_multiplex_workers
are retrieved unconditionally. For legacyjava_toolchain
s that pre-date these attributes,RuleContext#attributes().get()
will return the explicit default only if the attribute exists in the rule definition the target was analysed with.
As long as every Bazel that contains this JavaToolchain class also contains the updated rule definition, you are fine, but mixing remote and local repositories with mismatching versions could surface an NPE. A defensive pattern is:boolean headerCompilerSupportsWorkers = ruleContext.attributes().has("header_compiler_supports_workers") ? ruleContext.attributes().get("header_compiler_supports_workers", Type.BOOLEAN) : false;src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java (2)
134-136
: 👍 Always-param-file change looks goodForcing a param-file removes command-line length heuristics and eliminates issues with argument-quoting. No functional concerns observed.
494-497
: Good catch: tools now include Turbine wrapper itselfSupplying
headerCompiler.tool().getFilesToRun()
ensures the remote executor receives the wrapper
and any launcher scripts – preventing “file not found” errors observed when using sandboxed
RBE.src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/BUILD (1)
10-15
: LGTM! Build configuration updated for the new worker wrapper.The build configuration has been properly updated to use the new
TurbineWorkerWrapper
class as the main entry point and includes the necessary dependencies for the worker functionality.src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java (6)
100-101
: LGTM! New attributes properly added to the Java toolchain provider.These attributes will allow the build system to configure whether Turbine header compiler should run in worker and multiplex worker modes.
154-155
: LGTM! Parameters correctly passed to constructor.The new attributes are properly passed to the constructor from the create method.
189-190
: LGTM! Fields added to store the worker support attributes.The fields are correctly declared as private final, maintaining the class's immutability.
224-225
: LGTM! Constructor parameters added for the new attributes.The constructor is properly updated to accept the new parameters.
258-259
: LGTM! Constructor correctly initializes the new fields.The fields are properly initialized from the constructor parameters.
432-440
: LGTM! Getter methods implemented for the new attributes.The getter methods follow the same pattern as existing getters in the class and provide proper access to the new header compiler worker support flags.
src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineWorkerWrapper.java (1)
18-43
: LGTM! Worker mode implementation follows the established pattern.The implementation correctly handles the
--persistent_worker
flag and properly sets up the WorkRequestHandler to process requests. The worker infrastructure is configured with appropriate error handling and exit strategy.
ImmutableMap.Builder<String, String> executionInfoBuilder = ImmutableMap.builder(); | ||
executionInfoBuilder.putAll( | ||
TargetUtils.getExecutionInfo(ruleContext.getRule(), ruleContext.isAllowTagsPropagation())); | ||
if (javaConfiguration.inmemoryJdepsFiles()) { | ||
executionInfo = | ||
ImmutableMap.of( | ||
ExecutionRequirements.REMOTE_EXECUTION_INLINE_OUTPUTS, | ||
outputDepsProto.getExecPathString()); | ||
executionInfoBuilder.put( | ||
ExecutionRequirements.REMOTE_EXECUTION_INLINE_OUTPUTS, | ||
outputDepsProto.getExecPathString()); | ||
} | ||
if (javaToolchain.getHeaderCompilerSupportsWorkers()) { | ||
executionInfoBuilder.putAll(ExecutionRequirements.WORKER_MODE_ENABLED); | ||
} | ||
if (javaToolchain.getHeaderCompilerSupportsMultiplexWorkers()) { | ||
executionInfoBuilder.putAll(ExecutionRequirements.WORKER_MULTIPLEX_MODE_ENABLED); | ||
} | ||
ImmutableMap<String, String> executionInfo = executionInfoBuilder.build(); | ||
if (useDirectClasspath) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible duplicate-key crash when rule tags already enable worker mode
TargetUtils.getExecutionInfo()
may already return the key contained in
ExecutionRequirements.WORKER_MODE_ENABLED
(typically "supports-workers":"1"
).
Calling executionInfoBuilder.putAll()
twice with the same key will raise an
IllegalArgumentException
at build time because ImmutableMap.Builder
forbids duplicates, even
when the value is identical.
- if (javaToolchain.getHeaderCompilerSupportsWorkers()) {
- executionInfoBuilder.putAll(ExecutionRequirements.WORKER_MODE_ENABLED);
- }
+ if (javaToolchain.getHeaderCompilerSupportsWorkers()
+ && !executionInfoBuilder.buildOrThrow()
+ .containsKey(ExecutionRequirements.WORKER_MODE_ENABLED.keySet().iterator().next())) {
+ executionInfoBuilder.putAll(ExecutionRequirements.WORKER_MODE_ENABLED);
+ }
(The same guard is needed for the multiplex variant.)
Failing fast here would surface as an unexplained analysis exception to users.
Committable suggestion skipped: line range outside the PR's diff.
Implement a wrapper to support Turbine worker mode.
But how to publish java_tools?
not using worker:


using worker:
Summary by CodeRabbit
New Features
Bug Fixes
Chores