From d9e55e53488e1f2d155265f2142f217a4f760de8 Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Thu, 20 Nov 2025 11:42:50 -0600 Subject: [PATCH] Set local task exit status when time limit is exceeded Signed-off-by: Ben Sherman --- .../executor/local/LocalTaskHandler.groovy | 1 + .../local/LocalTaskHandlerTest.groovy | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/modules/nextflow/src/main/groovy/nextflow/executor/local/LocalTaskHandler.groovy b/modules/nextflow/src/main/groovy/nextflow/executor/local/LocalTaskHandler.groovy index 0bad8bb9c7..5c06f96958 100644 --- a/modules/nextflow/src/main/groovy/nextflow/executor/local/LocalTaskHandler.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/executor/local/LocalTaskHandler.groovy @@ -218,6 +218,7 @@ class LocalTaskHandler extends TaskHandler implements FusionAwareTask { */ if( elapsedTimeMillis() > wallTimeMillis ) { destroy() + task.exitStatus = process.exitValue() task.stdout = outputFile task.stderr = errorFile task.error = new ProcessException("Process exceeded running time limit (${task.config.getTime()})") diff --git a/modules/nextflow/src/test/groovy/nextflow/executor/local/LocalTaskHandlerTest.groovy b/modules/nextflow/src/test/groovy/nextflow/executor/local/LocalTaskHandlerTest.groovy index dcb4afaa2b..3126f1f246 100644 --- a/modules/nextflow/src/test/groovy/nextflow/executor/local/LocalTaskHandlerTest.groovy +++ b/modules/nextflow/src/test/groovy/nextflow/executor/local/LocalTaskHandlerTest.groovy @@ -21,10 +21,13 @@ import java.nio.file.Path import nextflow.Global import nextflow.container.DockerConfig +import nextflow.exception.ProcessException import nextflow.file.http.XPath import nextflow.processor.TaskBean import nextflow.processor.TaskConfig import nextflow.processor.TaskRun +import nextflow.processor.TaskStatus +import nextflow.util.Duration import spock.lang.Specification /** * @@ -83,4 +86,33 @@ class LocalTaskHandlerTest extends Specification { cleanup: builder?.redirectOutput()?.file()?.delete() } + + def 'should kill task when task exceeds time limit' () { + given: + def workDir = Path.of('/tmp/test-work-dir') + def task = Mock(TaskRun) { + getWorkDir() >> workDir + getConfig() >> Mock(TaskConfig) { + getTime() >> Duration.of(100) + } + } + and: + def handler = Spy(new LocalTaskHandler(task, Mock(LocalExecutor))) { + buildTaskWrapper() >> {} + elapsedTimeMillis() >> 200 + } + handler.@process = Mock(Process) { + exitValue() >> 143 // Typical exit code for SIGTERM + } + handler.status = TaskStatus.RUNNING + + when: + def completed = handler.checkIfCompleted() + + then: + completed == true + 1 * task.setExitStatus(143) + 1 * task.setError(_ as ProcessException) + handler.status == TaskStatus.COMPLETED + } }