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

Remove some coupling between the client and daemon #29167

Merged
merged 14 commits into from
May 16, 2024
Merged

Conversation

adammurdoch
Copy link
Member

@adammurdoch adammurdoch commented May 15, 2024

Context

This PR removes some usages of "build process" (eg the daemon) types from the client implementation.

  • In particular, split BuildRequestContext to instead use separate client-side and daemon-side context. This allows the types to carry different information represented using different types.

It also applies some clean-up of the "daemon-protocol", "daemon-services", "client-services" and "build-state" projects:

  • Allow projects to declare cross build session services, so that "build-state" does not need to know about them all.
  • Move service registration around so that "build-state" does need to know about services implemented in "core", and "launcher" does not need to know about services implemented in "build-state".
  • Moved classes to new packages to avoid split packages.
  • Some renames to fix (my) spelling error.

Contributor Checklist

  • Review Contribution Guidelines.
  • Make sure that all commits are signed off to indicate that you agree to the terms of Developer Certificate of Origin.
  • Make sure all contributed code can be distributed under the terms of the Apache License 2.0, e.g. the code was written by yourself or the original code is licensed under a license compatible to Apache License 2.0.
  • Check "Allow edit from maintainers" option in pull request so that additional changes can be pushed by Gradle team.
  • Provide integration tests (under <subproject>/src/integTest) to verify changes from a user perspective.
  • Provide unit tests (under <subproject>/src/test) to verify logic.
  • Update User Guide, DSL Reference, and Javadoc for public-facing changes.
  • Ensure that tests pass sanity check: ./gradlew sanityCheck.
  • Ensure that tests pass locally: ./gradlew <changed-subproject>:quickTest.

Reviewing cheatsheet

Before merging the PR, comments starting with

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

@adammurdoch adammurdoch requested review from a team as code owners May 15, 2024 20:01
@adammurdoch adammurdoch self-assigned this May 15, 2024

dependencies {
api(project(":core"))
api(project(":base-services"))
api(project(":java-language-extensions"))
api(project(":core-api"))
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved some service registration back to core, where the services are implemented.


public class BuildProcessScopeServices {
void configure(ServiceRegistration registration, ClassLoaderRegistry classLoaderRegistry) {
final List<PluginServiceRegistry> pluginServiceFactories = new DefaultServiceLocator(classLoaderRegistry.getRuntimeClassLoader(), classLoaderRegistry.getPluginsClassLoader()).getAll(PluginServiceRegistry.class);
Copy link
Member Author

Choose a reason for hiding this comment

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

"build-state" is now responsible for locating all the plugin service registries, moved out of "core".

GradleUserHomeScopeServiceRegistry userHomeServiceRegistry,
ServiceRegistry globalServices
) {
return new SetupLoggingActionExecutor(
Copy link
Member Author

Choose a reason for hiding this comment

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

"build-state" is responsible for creating the outer most "build pipeline", which is the main entry point used by all of the things that need to run a build in the current process. Moved out of "launcher".

@@ -42,7 +42,8 @@ public BuildProcessState(
ServiceRegistryBuilder builder = ServiceRegistryBuilder.builder()
.scopeStrictly(Scope.Global.class)
.displayName("Global services")
.provider(new GlobalScopeServices(longLiving, agentStatus, additionalModuleClassPath));
.provider(new GlobalScopeServices(longLiving, agentStatus, additionalModuleClassPath))
Copy link
Member Author

Choose a reason for hiding this comment

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

GlobalScopeServices should be busted up, but this is a bit complicated, so in this PR leave it mostly unchanged.

@@ -110,118 +62,9 @@ void configure(ServiceRegistration registration, List<PluginServiceRegistry> plu
registration.add(BuildRequestMetaData.class, buildRequestMetaData);
registration.add(BuildClientMetaData.class, buildClientMetaData);
registration.add(BuildEventConsumer.class, buildEventConsumer);
registration.add(CalculatedValueContainerFactory.class);
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved some service registration back to core, where the services are implemented.

this.startParameter = startParameter;
}

void configure(ServiceRegistration registration) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved some service registration back to core, where the services are implemented.

/**
* A client-side host for {@link org.gradle.internal.invocation.BuildAction} execution.
*/
public class ClientBuildRequestContext {
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 new client-side context type, split out of BuildRequestContext. It mostly mirrors the daemon-side context, but can later gain some additional state, such as the InputStream to consume "stdin" from.

import org.gradle.internal.UncheckedException;

import java.io.IOException;

public class GradleLauncherMetaData implements BuildClientMetaData {
public class GradleLauncherMetaData {
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved to "daemon-protocol" and detangled from the "build process" type.

private final long startTime;
private final boolean interactive;
private final BuildActionParameters parameters;

public Build(UUID identifier, byte[] token, BuildAction action, BuildClientMetaData buildClientMetaData, long startTime, boolean interactive, BuildActionParameters parameters) {
public Build(UUID identifier, byte[] token, BuildAction action, GradleLauncherMetaData buildClientMetaData, long startTime, boolean interactive, BuildActionParameters parameters) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Use the shared type to carry client metadata from client to daemon.

import org.gradle.tooling.internal.provider.serialization.PayloadSerializer;
import org.gradle.tooling.internal.provider.serialization.WellKnownClassLoaderRegistry;

public class DaemonServices extends AbstractPluginServiceRegistry {
Copy link
Member Author

Choose a reason for hiding this comment

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

New service registry for the services implemented in "daemon-services", moved out of "launcher".

System.in,
globalServices.get(BuildExecutor.class)
);
BuildActionExecutor<BuildActionParameters, ClientBuildRequestContext> executor = new RunInProcess(
Copy link
Member Author

Choose a reason for hiding this comment

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

Use the client-side context instead of the daemon-side context in the gradle client, but when running in-process, use some adapters to convert client-side to daemon-side.

@@ -32,18 +30,18 @@
import org.gradle.tooling.internal.provider.action.ExecuteBuildAction;

public class RunBuildAction implements Runnable {
private final BuildActionExecutor<BuildActionParameters, BuildRequestContext> executer;
private final BuildActionExecutor<BuildActionParameters, ClientBuildRequestContext> executor;
Copy link
Member Author

Choose a reason for hiding this comment

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

Use client-side context in the gradle client.

@@ -53,7 +56,9 @@ protected void doBuild(final DaemonCommandExecution execution, Build build) {
DaemonConnectionBackedEventConsumer buildEventConsumer = new DaemonConnectionBackedEventConsumer(execution);
try {
BuildCancellationToken cancellationToken = execution.getDaemonStateControl().getCancellationToken();
BuildRequestContext buildRequestContext = new DefaultBuildRequestContext(build.getBuildRequestMetaData(), cancellationToken, buildEventConsumer);
DefaultBuildClientMetaData clientMetaData = new DefaultBuildClientMetaData(build.getBuildClientMetaData());
Copy link
Member Author

Choose a reason for hiding this comment

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

Adapt from shared protocol type to daemon-side context in the daemon.

registration.addProvider(new ToolingGlobalScopeServices());
}

@Override
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved some service registration to "daemon-services" and "build-state".

@@ -27,20 +27,20 @@
import org.gradle.launcher.exec.DefaultBuildActionParameters;
import org.gradle.tooling.internal.provider.connection.ProviderOperationParameters;

public class DaemonBuildActionExecuter implements BuildActionExecutor<ConnectionOperationParameters, BuildRequestContext> {
Copy link
Member Author

Choose a reason for hiding this comment

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

Use the client-side context in the tooling API client.

@@ -34,17 +34,17 @@
/**
* A {@link BuildActionExecutor} which routes Gradle logging to those listeners specified in the {@link ProviderOperationParameters} provided with a tooling api build request.
*/
public class LoggingBridgingBuildActionExecuter implements BuildActionExecutor<ConnectionOperationParameters, BuildRequestContext> {
public class LoggingBridgingBuildActionExecuter implements BuildActionExecutor<ConnectionOperationParameters, ClientBuildRequestContext> {
Copy link
Member Author

Choose a reason for hiding this comment

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

Use the client-side context in the tooling API client.

@@ -258,10 +258,10 @@ private Object run(
Parameters parameters
) {
try {
BuildActionExecutor<ConnectionOperationParameters, BuildRequestContext> executer = createExecuter(providerParameters, parameters);
Copy link
Member Author

Choose a reason for hiding this comment

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

Use the client-side context in the tooling API client.

import java.io.Closeable;
import java.io.File;

public class CoreBuildSessionServices {
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved some service registrations back to "core".

import org.gradle.internal.work.DefaultWorkerLeaseService;
import org.gradle.internal.work.WorkerLeaseService;

public class CoreCrossBuildSessionServices {
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved some service registrations back to "core".

@adammurdoch adammurdoch added this pull request to the merge queue May 16, 2024
@bot-gradle bot-gradle added this to the 8.9 RC1 milestone May 16, 2024
Merged via the queue into master with commit 8e4699b May 16, 2024
26 of 27 checks passed
@adammurdoch adammurdoch deleted the am/client-detangle branch May 16, 2024 21:45
@alllex alllex added the in:internal-services Internal services dependency injection label May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in:daemon in:internal-services Internal services dependency injection
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants