On Jun 19, 2009, at 9:44 PM, Steve Appling wrote:
I am interested in ways to short circuit task execution for the
purpose of optimization. I would love to see some of this in 0.7
and would be glad to contribute.
Here are some ideas:
1) Add an "onlyIf" method to Task that is given a closure. The
closure would be executed before the first action of the task and
would cancel execution of the task (with appropriate lifecycle
message) if it returned false. This closure would have as a
delegate an optimization container with some helper methods that
would provide more convenient access to change detection (among
other things). Then you could do:
mytask.onlyIf {
timestampChanged 'src/main/mysrc'
// or contentsChanged 'src/main/mysrc'
}
I like the syntax. I'm also thinking about the following use cases:
I want to _add_ a custom onlyIf condition.
I want to remove a condition.
What you can do to add:
oldOnlyIf = myTask.onlyIf
myTask.onlyIf {
value == 5 && oldOnlyIf.call()
}
It is not very nice but it works. So I think that should be good
enough for 0.7. Later we might add a spec like API.
Removing and replacing is obviously easy.
2) Running a clean should probably remove the change detection state
information for a project (or at least the clean task should be able
to be configured to do this conveniently).
That would be important.
3) I would like some general way for tasks to indicate that they did
anything. Perhaps task.getDidWork(). BTW, I figured out how to do
this for gradle's use of ant.javac and can now tell if it really
compiled anything.
This makes sense.
4) I would like to be able to specify that a chain of dependent
tasks only execute a task if Task.didWork is true for all of its
dependents. Note that this is not always desired, so you need to be
able to turn this on and off. I'm not sure of the best way to
configure this. If we use the onlyIf method suggested above, it
might take another closure to check this that would be returned from
a "needed" method. This would look like:
myTask.onlyIf(needed())
This probably should be the default for tests, but perhaps not for
all Tasks.
Javac is already checking to see if the source files are out of date
with the classes, so I don't think that the javac task needs to use
the new changedetection.
Right. But we can set the didWork flag.
This would, however let you stop other tasks in the chain (like
test) if nothing needed to be compiled.
Right.
(unrelated: I would also like to see an option on compile to use
Ant's depend task. I think the current dependencyTracking option
doesn't work with the modern compiler. )
Interesting. This deserves a discussion on its own. I think this is an
important topic.
Other types of tasks could make good use of Tom's change detection.
5) We probably want a command line option to be able to disable all
of these optimizations. Sometimes you really want to force a build
with no optimizations (without running clean).
Right. A contrived example: You want the tests to be run even if
nothing needs to be compiled as your tests depend on some dynamic
properties retrieved from the network. Adam has come up with the idea
of introducing the notion of a build type. We should discuss this now
in more detail.
- Hans
--
Hans Dockter
Gradle Project Manager
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email