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

Add initializer for in-process Gradle executor #29142

Open
wants to merge 6 commits into
base: release
Choose a base branch
from

Conversation

wolfs
Copy link
Member

@wolfs wolfs commented May 14, 2024

Avoiding strange static state caused by unit tests that causes flaky test failures.

The real culprit seems to be the reuse of the cache inside the AsmBackedClassGenerator:

if (GENERATED_CLASSES_CACHES.get() == null) {
if (GENERATED_CLASSES_CACHES.compareAndSet(null, cacheFactory.newClassMap())) {
ClassGeneratorSuffixRegistry.register(suffix);
}
}
generatedClasses = GENERATED_CLASSES_CACHES.get();
} else {

If some test (e.g. WorkerProcessIntegrationTest) creates an AsmBackedClassGenerator with the TestCrossBuildInMemoryCacheFactory first, then all other tests will get a TestCache as the cache implementation. The TestCache is not thread-safe, and the ConcurrentClassDecorationSpec would break.

Making TestCache thread-safe fixes the immediate breakage of the ConcurrentClassDecorationSpec, but this is only a symptom and doesn't address the root cause. So we add the initializer for Global services instead so we don't get into the situation.

Avoiding strange static state caused by unit tests that causes flaky test failures.
@wolfs wolfs added this to the 8.8 RC2 milestone May 14, 2024
@wolfs wolfs self-assigned this May 14, 2024
@wolfs wolfs requested a review from a team as a code owner May 14, 2024 13:56
@wolfs wolfs requested a review from a team as a code owner May 14, 2024 13:58
@wolfs wolfs requested a review from mlopatkin May 14, 2024 13:58
void start() {
if (GradleContextualExecuter.embedded ) {
AbstractGradleExecuter.GLOBAL_SERVICES.get(ObjectFactory)
}
Copy link
Member

Choose a reason for hiding this comment

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

Can we add some more comments about why this is happening only in embedded mode, and why this specific service is being queried?

Copy link
Member Author

Choose a reason for hiding this comment

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

Is the Javadoc on the class enough for describing why it only happens for embedded mode? I can add something here why we query ObjectFactory.

Copy link
Member Author

Choose a reason for hiding this comment

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

I left some more comments.

@@ -115,6 +116,7 @@ public abstract class AbstractGradleExecuter implements GradleExecuter, Resettab
.build();

private static final JvmVersionDetector JVM_VERSION_DETECTOR = GLOBAL_SERVICES.get(JvmVersionDetector.class);
private static final ObjectFactory objectFactory = GLOBAL_SERVICES.get(ObjectFactory.class);
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this an unused field now? Can we clarify with a comment?

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 was a leftover, I removed it.

@wolfs wolfs requested a review from lptr May 15, 2024 07:15
@wolfs wolfs removed this from the 8.8 RC2 milestone May 16, 2024
Copy link
Member

@mlopatkin mlopatkin left a comment

Choose a reason for hiding this comment

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

Thanks! Comments really make it clear.

* may have a test implementation instead of the real thing when a unit test runs first.
*/
@Issue("https://github.com/gradle/gradle-private/issues/3534")
public class InProcessGradleExecutorInitialization implements IGlobalExtension {
Copy link
Member

Choose a reason for hiding this comment

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

💅 maybe reference this class in the InProcessGradleExecutor javadocs too? Global extensions are not something used often in our codebase (in fact, I've learned about them right now), and the extra visibility can save some time in the future for people figuring out how the executer is being initialized.

@lptr
Copy link
Member

lptr commented May 27, 2024

Shall we merge this?

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

Successfully merging this pull request may close these issues.

None yet

5 participants