From 7521efa02aa0564f935048c999828f8c8e331648 Mon Sep 17 00:00:00 2001 From: Nick Bulleid Date: Thu, 8 Jul 2021 11:48:44 +0100 Subject: [PATCH] Add PauseAction when throttling pipelines --- .../ThrottleQueueTaskDispatcher.java | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java index e04d6322..262c01a3 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java @@ -41,6 +41,7 @@ import org.jenkinsci.plugins.workflow.graph.StepNode; import org.jenkinsci.plugins.workflow.graphanalysis.LinearBlockHoppingScanner; import org.jenkinsci.plugins.workflow.steps.StepDescriptor; +import org.jenkinsci.plugins.workflow.support.actions.PauseAction; import org.jenkinsci.plugins.workflow.support.concurrent.Timeout; import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution.PlaceholderTask; @@ -58,14 +59,17 @@ public class ThrottleQueueTaskDispatcher extends QueueTaskDispatcher { @Deprecated @Override public @CheckForNull CauseOfBlockage canTake(Node node, Task task) { + CauseOfBlockage cause = null; if (Jenkins.getAuthentication().equals(ACL.SYSTEM)) { - return canTakeImpl(node, task); - } - - // Throttle-concurrent-builds requires READ permissions for all projects. - try (ACLContext ctx = ACL.as(ACL.SYSTEM)) { - return canTakeImpl(node, task); + cause = canTakeImpl(node, task); + } else { + // Throttle-concurrent-builds requires READ permissions for all projects. + try (ACLContext ctx = ACL.as(ACL.SYSTEM)) { + cause = canTakeImpl(node, task); + } } + updatePauseAction(task, cause); + return cause; } private CauseOfBlockage canTakeImpl(Node node, Task task) { @@ -214,14 +218,17 @@ private boolean shouldBeThrottled(@NonNull Task task, @CheckForNull ThrottleJobP } private CauseOfBlockage canRun(Task task, ThrottleJobProperty tjp, List pipelineCategories) { + CauseOfBlockage cause = null; if (Jenkins.getAuthentication().equals(ACL.SYSTEM)) { - return canRunImpl(task, tjp, pipelineCategories); - } - + cause = canRunImpl(task, tjp, pipelineCategories); + } else { // Throttle-concurrent-builds requires READ permissions for all projects. - try (ACLContext ctx = ACL.as(ACL.SYSTEM)) { - return canRunImpl(task, tjp, pipelineCategories); + try (ACLContext ctx = ACL.as(ACL.SYSTEM)) { + cause = canRunImpl(task, tjp, pipelineCategories); + } } + updatePauseAction(task, cause); + return cause; } private CauseOfBlockage canRunImpl(Task task, ThrottleJobProperty tjp, List pipelineCategories) { @@ -682,5 +689,26 @@ private int getMaxConcurrentPerNodeBasedOnMatchingLabels( return maxConcurrentPerNodeLabeledIfMatch; } + private void updatePauseAction(Task task, CauseOfBlockage cause) { + if (task instanceof PlaceholderTask) { + PlaceholderTask placeholderTask = (PlaceholderTask)task; + try { + FlowNode flowNode = placeholderTask.getNode(); + if (cause != null) { + if (flowNode.getAction(PauseAction.class) == null) { + flowNode.addAction(new PauseAction(cause.getShortDescription())); + } + } else { + PauseAction.endCurrentPause(flowNode); + } + } catch (IOException|InterruptedException e) { + LOGGER.log( + Level.WARNING, + "Error setting pause action on pipeline {0}: {1}", + new Object[] {task.getDisplayName(), e}); + } + } + } + private static final Logger LOGGER = Logger.getLogger(ThrottleQueueTaskDispatcher.class.getName()); }