On 22/03/2013, at 12:32 PM, Marcin Erdmann <marcin.erdm...@proxerd.pl> 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

Reply via email to