Skip to content

Commit 9aee5a7

Browse files
Add PauseAction when throttling pipelines
1 parent 05f713e commit 9aee5a7

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.jenkinsci.plugins.workflow.graph.StepNode;
4242
import org.jenkinsci.plugins.workflow.graphanalysis.LinearBlockHoppingScanner;
4343
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
44+
import org.jenkinsci.plugins.workflow.support.actions.PauseAction;
4445
import org.jenkinsci.plugins.workflow.support.concurrent.Timeout;
4546
import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution.PlaceholderTask;
4647

@@ -58,14 +59,17 @@ public class ThrottleQueueTaskDispatcher extends QueueTaskDispatcher {
5859
@Deprecated
5960
@Override
6061
public @CheckForNull CauseOfBlockage canTake(Node node, Task task) {
62+
CauseOfBlockage cause = null;
6163
if (Jenkins.getAuthentication().equals(ACL.SYSTEM)) {
62-
return canTakeImpl(node, task);
63-
}
64-
65-
// Throttle-concurrent-builds requires READ permissions for all projects.
66-
try (ACLContext ctx = ACL.as(ACL.SYSTEM)) {
67-
return canTakeImpl(node, task);
64+
cause = canTakeImpl(node, task);
65+
} else {
66+
// Throttle-concurrent-builds requires READ permissions for all projects.
67+
try (ACLContext ctx = ACL.as(ACL.SYSTEM)) {
68+
cause = canTakeImpl(node, task);
69+
}
6870
}
71+
updatePauseAction(task, cause);
72+
return cause;
6973
}
7074

7175
private CauseOfBlockage canTakeImpl(Node node, Task task) {
@@ -214,14 +218,17 @@ private boolean shouldBeThrottled(@NonNull Task task, @CheckForNull ThrottleJobP
214218
}
215219

216220
private CauseOfBlockage canRun(Task task, ThrottleJobProperty tjp, List<String> pipelineCategories) {
221+
CauseOfBlockage cause = null;
217222
if (Jenkins.getAuthentication().equals(ACL.SYSTEM)) {
218-
return canRunImpl(task, tjp, pipelineCategories);
219-
}
220-
223+
cause = canRunImpl(task, tjp, pipelineCategories);
224+
} else {
221225
// Throttle-concurrent-builds requires READ permissions for all projects.
222-
try (ACLContext ctx = ACL.as(ACL.SYSTEM)) {
223-
return canRunImpl(task, tjp, pipelineCategories);
226+
try (ACLContext ctx = ACL.as(ACL.SYSTEM)) {
227+
cause = canRunImpl(task, tjp, pipelineCategories);
228+
}
224229
}
230+
updatePauseAction(task, cause);
231+
return cause;
225232
}
226233

227234
private CauseOfBlockage canRunImpl(Task task, ThrottleJobProperty tjp, List<String> pipelineCategories) {
@@ -682,5 +689,26 @@ private int getMaxConcurrentPerNodeBasedOnMatchingLabels(
682689
return maxConcurrentPerNodeLabeledIfMatch;
683690
}
684691

692+
private void updatePauseAction(Task task, CauseOfBlockage cause) {
693+
if (task instanceof PlaceholderTask) {
694+
PlaceholderTask placeholderTask = (PlaceholderTask)task;
695+
try {
696+
FlowNode flowNode = placeholderTask.getNode();
697+
if (cause != null) {
698+
if (flowNode.getAction(PauseAction.class) == null) {
699+
flowNode.addAction(new PauseAction(cause.getShortDescription()));
700+
}
701+
} else {
702+
PauseAction.endCurrentPause(flowNode);
703+
}
704+
} catch (IOException|InterruptedException e) {
705+
LOGGER.log(
706+
Level.WARNING,
707+
"Error setting pause action on pipeline {0}: {1}",
708+
new Object[] {task.getDisplayName(), e});
709+
}
710+
}
711+
}
712+
685713
private static final Logger LOGGER = Logger.getLogger(ThrottleQueueTaskDispatcher.class.getName());
686714
}

src/test/java/hudson/plugins/throttleconcurrents/TestUtil.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
import hudson.model.Computer;
99
import hudson.model.Executor;
1010
import hudson.model.Node;
11+
import hudson.model.Queue;
1112
import hudson.model.queue.CauseOfBlockage;
1213
import hudson.slaves.DumbSlave;
1314
import hudson.slaves.RetentionStrategy;
1415

1516
import jenkins.model.queue.CompositeCauseOfBlockage;
1617

1718
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
19+
import org.jenkinsci.plugins.workflow.support.actions.PauseAction;
1820
import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution;
1921
import org.junit.rules.TemporaryFolder;
2022
import org.jvnet.hudson.test.JenkinsRule;
@@ -106,6 +108,13 @@ static Set<String> getBlockageReasons(CauseOfBlockage cob) {
106108
}
107109
}
108110

111+
static void hasPauseActionForItem(Queue.Item item) throws Exception {
112+
assertTrue(item.task instanceof ExecutorStepExecution.PlaceholderTask);
113+
ExecutorStepExecution.PlaceholderTask task =
114+
(ExecutorStepExecution.PlaceholderTask)item.task;
115+
assertNotNull(task.getNode().getAction(PauseAction.class));
116+
}
117+
109118
static void hasPlaceholderTaskForRun(Node n, WorkflowRun r) throws Exception {
110119
for (Executor exec : n.toComputer().getExecutors()) {
111120
if (exec.getCurrentExecutable() != null) {

src/test/java/hudson/plugins/throttleconcurrents/ThrottleStepTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public void onePerNode() throws Exception {
9898
assertThat(
9999
blockageReasons,
100100
hasItem(Messages._ThrottleQueueTaskDispatcher_MaxCapacityOnNode(1).toString()));
101+
TestUtil.hasPauseActionForItem(queuedItem);
101102
assertEquals(1, agent.toComputer().countBusy());
102103
TestUtil.hasPlaceholderTaskForRun(agent, firstJobFirstRun);
103104

0 commit comments

Comments
 (0)