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