@Retention(value=RUNTIME) @Target(value=TYPE) @Incubating public @interface ParallelizableTask
Tasks are not parallelizable by default because it is possible for tasks to interfere with each other in unsafe ways. That is, it is possible for tasks to mutate shared data structures during their execution. The presence of this annotation on task class declares that the task does not do this and is therefore parallelizable.
For a task to be safely parallelizable, it should not change any data that may be read by other tasks. It should not, for example, update project extensions, other tasks or any other shared data. It may change internal variables and properties of the task, the filesystem and other external resources.
This annotation is not inherited. A task class that extends from another task class that declares itself to be parallel safe is not implicitly also parallel safe. If the subclass is indeed parallel safe, it must also have this annotation.
Any task that has custom actions (i.e. ones added via Task.doLast(org.gradle.api.Action)
or Task.doFirst(org.gradle.api.Action)
)
is not considered parallelizable even if its type carries this annotation.
This is because it cannot be known whether the added action is parallel safe or not.
Any two tasks that declare overlapping file system outputs will not be run in parallel with each other even if they carry this annotation, to prevent data corruption. In general tasks should not be configured to write to the same file or directory on the filesystem and they should only write into filesystem locations that are declared as their outputs for this reason. Two tasks that write to overlapping parts of the filesystem are only prevented from running in parallel with each other, not other parallel enabled tasks.
Care must be taken with symbolic links, and other types of file system links, as Gradle does not exhaustively check that outputs of tasks do not overlap.
It only considers the top level declared output files
and output directories
of the task.
If a task traverses a link that is a child of a declared output in order to change or create files, the real location of the files will not be considered. However, declared outputs that are children of links are resolved to their real location.
In order to prevent two tasks from executing in parallel, a Task.mustRunAfter(Object...)
relationship can be set up between the tasks.