There is an XSL task which processes many files from one directory into another. This process takes some time per file but could in theory be highly parallelized as all files are independent. As I was wondering if this work could be in any way parallelized I tried to combine @Incremental
with a WorkerQueue
, but I can’t get it to work. Not sure what I’m doing wrong.
interface XSLTWorkParameters extends WorkParameters {
RegularFileProperty getStylesheet()
Property<File> getInputFile()
Property<File> getTargetFile()
}
abstract class TransformWorkAction implements WorkAction<XSLTWorkParameters> {
@Override
public void execute() {
try {
File stylesheet = getParameters().getStylesheet().get().asFile
File inputFile = getParameters().getInputFile().get()
File targetFile = getParameters().getTargetFile().get()
def transformer = new Transformer(stylesheet)
println "Processing: " + inputFile
transformer.transform(inputFile, targetFile)
} catch (Exception e) {
throw new RuntimeException(e)
}
}
}
abstract class TransformMultiTask extends DefaultTask {
@Incremental
@PathSensitive(PathSensitivity.NAME_ONLY)
@InputDirectory
abstract DirectoryProperty getInput()
@PathSensitive(PathSensitivity.NAME_ONLY)
@InputFile
abstract RegularFileProperty getStylesheet()
@OutputDirectory
abstract DirectoryProperty getOutput()
@Inject
abstract public WorkerExecutor getWorkerExecutor()
@TaskAction
void processFiles(InputChanges inputChanges) {
def cleanOutputDir = !inputChanges.incremental
if(cleanOutputDir) {
logger.info('Cleaning: {}', output.get().asFile)
project.delete(output)
output.get().asFile.mkdirs()
}
WorkQueue workQueue = getWorkerExecutor().noIsolation()
logger.info('Stylesheet: {}', stylesheet.get().asFile)
inputChanges.getFileChanges(input).each { change ->
if (change.fileType == FileType.DIRECTORY) return
def targetFile = output.file(change.normalizedPath).get().asFile
if (change.changeType == ChangeType.REMOVED) {
logger.info('Removing: {}', targetFile)
targetFile.delete()
} else {
workQueue.submit(
TransformWorkAction.class,
parameters -> {
parameters.getStylesheet().set(getStylesheet())
parameters.getInputFile().set(change.file)
parameters.getTargetFile().set(targetFile)
}
)
}
}
}
}
Using Gradle 7.6.2 it results in
* What went wrong:
Execution failed for task ':my.project:generateFiles'.
> A failure occurred while executing TransformWorkAction
> Could not isolate value XSLTWorkParameters_Decorated@6f261e34 of type XSLTWorkParameters
> java.lang.StackOverflowError (no error message)
The stack-overflow comes from
Caused by: org.gradle.internal.snapshot.impl.IsolationException: Could not isolate value XSLTWorkParameters_Decorated@6f261e34 of type XSLTWorkParameters
at org.gradle.internal.snapshot.impl.DefaultIsolatableFactory.isolate(DefaultIsolatableFactory.java:51)
at org.gradle.workers.internal.DefaultActionExecutionSpecFactory.newIsolatedSpec(DefaultActionExecutionSpecFactory.java:49)
at org.gradle.workers.internal.DefaultWorkerExecutor.submitWork(DefaultWorkerExecutor.java:198)
... 120 more
Caused by: java.lang.StackOverflowError
at org.gradle.internal.snapshot.impl.AbstractValueProcessor.processValue(AbstractValueProcessor.java:130)
at org.gradle.internal.snapshot.impl.AbstractValueProcessor.processValue(AbstractValueProcessor.java:134)
at org.gradle.internal.snapshot.impl.AbstractValueProcessor.processValue(AbstractValueProcessor.java:134)
....