On 26/03/2013, at 7:34 PM, Adam Murdoch <adam.murd...@gradleware.com> wrote:

> 
> 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.

Actually, this doesn't work for shared dependencies, as there's also an 
ordering constraint on a finaliser. We can tweak it so that we split finaliser 
relationships up into 2 parts: the ordering part which is the same as a soft 
dependency, and the triggering part that switches the task state to `must run`. 
The dependencies of a finaliser don't pick up the ordering part, but they do 
pick up the triggering part.


> 
>> - 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
> 


--
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