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

Pass task dependency list to DefaultTaskOperationDescriptor #28252

Open
mgroth0 opened this issue Feb 27, 2024 · 5 comments
Open

Pass task dependency list to DefaultTaskOperationDescriptor #28252

mgroth0 opened this issue Feb 27, 2024 · 5 comments
Labels
a:feature A new functionality in:build-services Shared Build Services

Comments

@mgroth0
Copy link

mgroth0 commented Feb 27, 2024

Current Behavior

TaskFinishEvent.dependencies throws an UnsupportedOperationException:

The version of Gradle you connect to does not support that method.
To resolve the problem you can change/upgrade the target version of Gradle you connect to.
Alternatively, you can ignore this exception and read other information from the model.

This message seems a little misinformative, because as far as I know there is not any Gradle version that supports TaskFinishEvent.dependencies. Looking here in the master branch, we see that task dependency information is not passed to the DefaultTaskOperationDescriptor constructor.

Expected Behavior

We should be able to get task dependencies in a configuration-cache compatible way. Specifically, this would just require that task dependencies are passed to the DefaultTaskOperationDescriptor at the above linked line.

It would not be required to pass the list of dependencies as a list of objects in the model. If there is any concern about that, passing a list of strings for the task paths would be perfectly sufficient (at least for my use case).

Context (optional)

When migrating to the configuration cache, there are a new set of APIs that you must migrate to as well.

For example, you must migrate from reading artifact dependency information directly from a Configuration. Instead, you must read information from a ResolutionResult to ensure your build is configuration cache behavior.

When it comes to task dependencies, the old way would be to use the task graph:

gradle.taskGraph.whenReady { graph ->  
        graph.getDependencies(someTask)
}

This, however, is not configuration cache compatible. We are required to migrate to the new OperationCompletionListener API to get task dependency information in a configuration cache compatible way. The API appears to support getting task dependency information given that there exists TaskOperationDescriptor.getDependencies. And looking at the javadoc for the method we see:

    /**
     * Returns the dependencies of the task (other tasks and transforms), if available.
     *
     * @throws UnsupportedMethodException For Gradle versions older than 5.1, where this method is not supported.
     * @since 5.1
     */

The javadoc indicates that this method worked since 5.1 So, it is expected that this method will work in Gradle 8.6. And if this is not supported for the configuration cache, that leaves a gap in the API when using a configuration cache build.

Steps to Reproduce

  1. Register an OperationCompletionListener
  2. In the onFinish method, wait for a TaskFinishEvent.
  3. Try to get the dependencies of the task from there

Gradle version

8.6

Build scan URL (optional)

No response

Your Environment (optional)

No response

@mgroth0
Copy link
Author

mgroth0 commented Feb 27, 2024

related to #28250

@mgroth0
Copy link
Author

mgroth0 commented Feb 27, 2024

Is there any other API for getting task dependencies that is configuration cache compatible?

@ov7a
Copy link
Member

ov7a commented Feb 29, 2024

This issue needs a decision from the team responsible for that area. They have been informed. Response time may vary.

@ov7a ov7a added in:tooling-api 👋 team-triage Issues that need to be triaged by a specific team and removed to-triage labels Feb 29, 2024
@donat donat self-assigned this Mar 4, 2024
@donat
Copy link
Member

donat commented Mar 13, 2024

I'm a little confused here because the description mentions bits of the Gradle API and the Tooling API as well. I've attempted to create reproducers for both:

  • a simple tapi client, listening for TaskFinishEvents,
  • a gradle script printing task dependencies in the TaskGraph.whenReady callback.
    Both seems to work fine and produce no warnings when the configuration cache is enable.

Can you please provide a minimal reproducer? With that available I can continue the investigation.

@donat donat added to-triage and removed 👋 team-triage Issues that need to be triaged by a specific team labels Mar 13, 2024
@ov7a ov7a added the pending:reproducer Indicates that the issue requires a reproducer or will be closed after 7 days label Mar 14, 2024
@mgroth0
Copy link
Author

mgroth0 commented Mar 15, 2024

@donat thank you for taking a look at this. Sorry about the miscommunications.

I am happy to provide some sort of reproducer if needed but first let me try to clarify. The reason why TaskGraph.whenReady is incompatible with the configuration cache is not because it produces warnings. It is incompatible because it simply does not execute on a build that loads from the configuration cache.

For context, I am generating reports and trying to include task dependency information. Currently the main way I know about to extract task dependency info is in TaskGraph.whenReady. But then my task that generates a report will not work if the build loaded from the config cache because TaskGraph.whenReady never executed, and the task dependency info was never extracted.

Meanwhile, I am also extracting other task information like so:

val taskInfoExtractor = gradle.sharedServices.registerIfAbsent("taskInfoExtractor",TaskFinishHandler::class.java) {

}

(gradle as GradleInternal).serviceOf<BuildEventsListenerRegistry>().onTaskCompletion(taskInfoExtractor)

abstract class TaskFinishHandler : BuildService<BuildServiceParameters.None>, OperationCompletionListener {
    override fun onFinish(event: FinishEvent) {
        println("Hello task finish event")
    }
}

The FinishEvent provides me info about tasks which I could not get from taskGraph.whenReady, because the FinishEvent api allows me to see info about tasks at execution time such as the result of each task.

Also, most importantly, the FinishEvent based api always run, no matter if the build loaded from the configuration cache or not.

The expectation I have then is that I should be able to get everything I need in a config-cache compatible way (meaning not only that there are no warnings, but also that it works on builds that load from the config cache). The reason I created this issue is because I think it is impossible for users currrently to get task dependency information from a FinishEvent. Furthermore, looking at the implementation, I see that the amount of effort it might take the gradle team to expose task dependency info in FinishEvent might be pretty minimal (I could be wrong here and don't mean to assume, but it just looked like the information exists at the time the DefaultTaskOperationDescriptor is constructed but is simply not passed to it).

If DefaultTaskOperationDescriptor was just given task dependency info, then I would never have to rely on TaskGraph.whenReady for anything.

This issue does not involve any Tooling API consumer.

I hope this provides enough clarification but if a reproducer is still needed please let me know.

@github-actions github-actions bot removed the pending:reproducer Indicates that the issue requires a reproducer or will be closed after 7 days label Mar 15, 2024
@ov7a ov7a removed the to-triage label Mar 15, 2024
@donat donat removed their assignment Apr 8, 2024
@donat donat added a:investigation Issues requiring decision or investigation in:plugin-development in:configuration-cache Configuration Caching and removed a:bug in:tooling-api labels May 8, 2024
@mlopatkin mlopatkin added in:build-services Shared Build Services a:feature A new functionality and removed in:plugin-development in:configuration-cache Configuration Caching labels May 28, 2024
@mlopatkin mlopatkin removed a:investigation Issues requiring decision or investigation to-triage labels May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:feature A new functionality in:build-services Shared Build Services
Projects
None yet
Development

No branches or pull requests

4 participants