On 22/03/2013, at 12:32 PM, Marcin Erdmann <[email protected]> wrote:
> I'm about to start working on finalising tasks. Following are my initial
> thoughts about how I currently see the implementation:
>
> - the relationship between tasks is specified on the finalised task, like
> Adam suggested:
>
> tasks.withType(Reporting) {
> finalisedBy(buildDashboardTask)
> }
>
> plus all the other flavours of it just like for dependsOn and mustRunAfter
>
> - the relationship has to be stored on both the finalised task (to be able to
> add the finialising task to the graph when the finalised task is being added)
> and on the finalising task (to be able to use that info when verifying that
> at least one of the tasks it finalises has been executed and the finalising
> task is not otherwise required to be executed).
> - a new TaskExecutionState or a flag on TaskInfo has to be added to
> differentiate between a state where a task is a finaliser and is otherwise
> not required to be executed, so that it can be skipped when the finalised
> task(s) did not run for whatever reason as described in the design spec:
> https://github.com/gradle/gradle/blob/master/design-docs/reporting.md#implementation-approach-2
> - a new TaskExecuter that would skip execution of a finalising task if none
> of the finalised tasks run and the finalising task is otherwise not required
> to be executed - that information can only be obtained from TaskInfo so it
> would now need to be passed to TaskExecuter.execute()
I think it might be better to keep this knowledge in TaskInfo. More on this
below.
> - I have no idea on how to achieve skipping dependencies of a finalising task
> when the finalising task should be skipped - it gets really tricky as those
> dependencies might be made mandatory by making the finalising task mandatory
> after being added to the graph…
Add them all as finalisers of the target task when you're traversing the graph
down from a finaliser task - that is, a dependency of a finaliser of task A is
itself a finaliser of A.
> - Modify DefaultTaskExecutionPlan to go into "finaliser task mode only" after
> a task failure not handled by failureHandler; if in that mode then
> getNextReadyAndMatching() would use a Spec that only allows finaliser tasks,
> and (I don't know how to achieve that) finaliser task dependencies
I would split the `ready` state into several: `should run` and `must run` and
`should not run`. The entry tasks and any task with an incoming hard dependency
will be in `should run`. A finaliser task starts off as `should not run` and is
switched to `must run` once any of the tasks that it finalises is executed.
Before the first failure, the execution plan runs tasks in `should run` and
`must run` state. Following a failure, it runs only tasks in `must run` state
and continues until there are no such tasks left.
--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com
Join us at the Gradle Summit 2013, June 13th and 14th in Santa Clara, CA:
http://www.gradlesummit.com