Skip to content
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

Work around Gradle modifying system properties at configuration time #30210

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

Conversation

mlopatkin
Copy link
Member

@mlopatkin mlopatkin commented Aug 16, 2024

When compiling Kotlin scripts, Gradle sets up some system properties. However, because Gradle doesn't instrument the Kotlin runtime, these modifications go unnoticed to environment change tracker infrastructure. If any user code then observes these system properties after modification, it becomes part of the configuration cache fingerprint. Moreover, as nothing restores the changed values when checking the fingerprint, it never matches, causing a CC miss.

With this PR, a special "scope function" of EnvironmentChangeTracker can be used to detect changes made to system properties and update the state of the tracker accordingly. This isn't a perfect solution for concurrent use cases, but it should work well when there is only one "scope" that modifies system properties directly, and everything else is instrumented.

It is possible to enter the scope function after restoring the CC state, for example, for a precompiled script plugin project. There is no change tracking in this case.

Fixes #30145.

Reviewing cheatsheet

Before merging the PR, comments starting with

  • ❌ ❓must be fixed
  • 🤔 💅 should be fixed
  • 💭 may be fixed
  • 🎉 celebrate happy things

@mlopatkin mlopatkin self-assigned this Aug 16, 2024
@mlopatkin

This comment has been minimized.

@bot-gradle

This comment has been minimized.

@mlopatkin

This comment has been minimized.

@bot-gradle

This comment has been minimized.

@mlopatkin

This comment has been minimized.

@bot-gradle

This comment has been minimized.

When compiling Kotlin scripts, Gradle sets up some system properties.
However, because Gradle doesn't instrument the Kotlin runtime, these
modifications go unnoticed to environment change tracker infrastructure.
If any user code then observes these system properties after
modification, it becomes part of the configuration cache fingerprint.
Moreover, as nothing restores the changed values when checking the
fingerprint, it never matches, causing a CC miss.

We can figure out the fixed set of properties set by the compiler and
ignore them, but this set comes from the Kotlin (==third party) code so
we'll have to maintain it and update alongside Kotlin releases.

Instrumenting the Kotlin runtime to track system property updates in a
usual way is an option, but it is much more involved and can bring in
many unwanted inputs because of the Gradle runtime calling the Kotlin's
stdlib functions.

Restoring the system properties after compilation completes may also
work but introduces a potential for race conditions when other,
instrumented code may modify the system properties concurrently. Rolling
back that changes would be an error.
The KotlinCompilerEnvironment instance serves as a token to mark all
functions that may change the environment to configure the compiler. It
also separates the tracking setup from the code in KotlinCompiler.
@mlopatkin mlopatkin force-pushed the ml/30145/workaround-nio-sysprop-change branch from 4b700ea to 1b72e9f Compare August 25, 2024 20:14
@mlopatkin
Copy link
Member Author

@bot-gradle test ACC

@bot-gradle
Copy link
Collaborator

I've triggered the following builds for you. Click here to see all build failures.

@mlopatkin
Copy link
Member Author

@bot-gradle test this

@bot-gradle
Copy link
Collaborator

I've triggered the following builds for you. Click here to see all build failures.


buildFile("plugin/build.gradle", """
plugins {
id "org.gradle.kotlin.kotlin-dsl" version "5.1.0" // TODO(mlopatkin): this should be the "current" Kotlin DSL version but it isn't available for Groovy scripts.
Copy link
Member Author

Choose a reason for hiding this comment

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

💭 Could not find another way to apply kotlin-dsl plugin with Groovy DSL.

@@ -177,10 196,31 @@ class ConfigurationCacheEnvironmentChangeTracker(private val problemFactory: Pro
systemPropertiesCleared = true
mutatedSystemProperties.clear()
}

override fun <T : Any> withTrackingSystemPropertyChanges(action: Supplier<out T>): T {
Copy link
Member Author

Choose a reason for hiding this comment

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

☝️ This is the core non-trivial change.

@mlopatkin mlopatkin marked this pull request as ready for review August 25, 2024 20:29
@mlopatkin mlopatkin requested review from a team as code owners August 25, 2024 20:29
@mlopatkin mlopatkin requested review from abstratt and 6hundreds and removed request for a team August 25, 2024 20:29
@mlopatkin mlopatkin added this to the 8.11 RC1 milestone Aug 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Configuration Cache Miss due to idea.io.use.nio2 system property change
2 participants