-
-
Notifications
You must be signed in to change notification settings - Fork 274
[gradle] Symlink user cache dir when RJE_UNSAFE_CACHE
is set
#1448
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
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.
Summary of Changes
Hello @shs96c, 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!
This pull request introduces a key optimization for Gradle resolution performance within rules_jvm_external
. It refines the mechanism for utilizing a shared Gradle user cache when RJE_UNSAFE_CACHE
is active. The core change involves replacing the direct setting of the gradle.user.home
system property with a more robust symbolic linking approach, connecting the temporary project's cache directory to the user's global Gradle cache. This aims to mitigate timing-related issues and ensures a more reliable shared cache experience, with built-in error handling and informative logging for fallback scenarios.
Highlights
- Performance Improvement: The primary goal of this change is to significantly improve Gradle resolution times by leveraging a shared user cache when
RJE_UNSAFE_CACHE
is enabled. - Cache Handling Strategy: Instead of directly setting the
gradle.user.home
system property, the approach now involves creating a symbolic link from the temporary project's.gradle/caches
directory to the user's global.gradle/caches
directory. This avoids potential timing issues. - Robust Symlinking with Fallback: The implementation includes checks for the existence of the user's cache directory and robust error handling for symbolic link creation. If symlinking fails or the user cache is not found, the system gracefully falls back to using an isolated cache.
- Verbose Logging: Added verbose logging to provide clear feedback on whether the unsafe shared cache is being utilized via symlinking or if the system has reverted to an isolated cache.
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 by creating a comment using either /gemini <command>
or @gemini-code-assist <command>
. Below is a summary of the supported commands on the current page.
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 pull request 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 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. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
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.
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 changes the unsafe caching mechanism for Gradle resolutions to use symbolic links to the user's cache directory instead of setting gradle.user.home
. This is a solid approach to improve performance while avoiding potential timing issues. The implementation correctly falls back to an isolated cache if creating the symlink fails. I have one suggestion to make the check for the user's cache directory more robust.
if (Files.exists(userCaches)) { | ||
try { | ||
Path cacheSymlink = gradleCacheDir.resolve("caches"); | ||
Files.createSymbolicLink(cacheSymlink, userCaches); | ||
if (isVerbose()) { | ||
eventListener.onEvent( | ||
new LogEvent( | ||
"gradle", | ||
"Using unsafe shared cache", | ||
"Symlinked " + userCaches + " -> " + cacheSymlink)); | ||
} | ||
} catch (IOException e) { | ||
// If symlinking fails, fall back to isolated cache | ||
if (isVerbose()) { | ||
eventListener.onEvent( | ||
new LogEvent( | ||
"gradle", | ||
"Failed to create cache symlink, using isolated cache", | ||
e.getMessage())); | ||
} | ||
} | ||
} else if (isVerbose()) { | ||
eventListener.onEvent( | ||
new LogEvent( | ||
"gradle", | ||
"User gradle caches directory not found, using isolated cache", | ||
"Expected: " + userCaches)); | ||
} |
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.
Using Files.exists()
here could lead to issues if userCaches
points to a file instead of a directory. Files.exists()
returns true for files, and createSymbolicLink
would succeed, but Gradle would later fail when it expects a directory for its cache.
Using Files.isDirectory()
is more robust as it ensures that we only attempt to symlink if the target is a directory. I've also updated the logging in the else
branch to be more descriptive about why the symlink was not created.
if (Files.isDirectory(userCaches)) {
try {
Path cacheSymlink = gradleCacheDir.resolve("caches");
Files.createSymbolicLink(cacheSymlink, userCaches);
if (isVerbose()) {
eventListener.onEvent(
new LogEvent(
"gradle",
"Using unsafe shared cache",
"Symlinked " + userCaches + " -> " + cacheSymlink));
}
} catch (IOException e) {
// If symlinking fails, fall back to isolated cache
if (isVerbose()) {
eventListener.onEvent(
new LogEvent(
"gradle",
"Failed to create cache symlink, using isolated cache",
e.getMessage()));
}
}
} else if (isVerbose()) {
String reason = Files.exists(userCaches) ? "is not a directory" : "not found";
eventListener.onEvent(
new LogEvent(
"gradle",
"User gradle caches directory " + reason + ", using isolated cache",
"Expected: " + userCaches));
}
d345cdf
to
23c6061
Compare
This can significantly improve the time it takes to perform resolutions.