Skip to content

Commit

Permalink
Add PauseAction when throttling pipelines
Browse files Browse the repository at this point in the history
  • Loading branch information
nickb-carallon committed Jul 13, 2021
1 parent 05f713e commit 9aee5a7
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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) {
Expand Down Expand Up @@ -214,14 +218,17 @@ private boolean shouldBeThrottled(@NonNull Task task, @CheckForNull ThrottleJobP
}

private CauseOfBlockage canRun(Task task, ThrottleJobProperty tjp, List<String> 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<String> pipelineCategories) {
Expand Down Expand Up @@ -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());
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
import hudson.model.Computer;
import hudson.model.Executor;
import hudson.model.Node;
import hudson.model.Queue;
import hudson.model.queue.CauseOfBlockage;
import hudson.slaves.DumbSlave;
import hudson.slaves.RetentionStrategy;

import jenkins.model.queue.CompositeCauseOfBlockage;

import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.support.actions.PauseAction;
import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution;
import org.junit.rules.TemporaryFolder;
import org.jvnet.hudson.test.JenkinsRule;
Expand Down Expand Up @@ -106,6 +108,13 @@ static Set<String> getBlockageReasons(CauseOfBlockage cob) {
}
}

static void hasPauseActionForItem(Queue.Item item) throws Exception {
assertTrue(item.task instanceof ExecutorStepExecution.PlaceholderTask);
ExecutorStepExecution.PlaceholderTask task =
(ExecutorStepExecution.PlaceholderTask)item.task;
assertNotNull(task.getNode().getAction(PauseAction.class));
}

static void hasPlaceholderTaskForRun(Node n, WorkflowRun r) throws Exception {
for (Executor exec : n.toComputer().getExecutors()) {
if (exec.getCurrentExecutable() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public void onePerNode() throws Exception {
assertThat(
blockageReasons,
hasItem(Messages._ThrottleQueueTaskDispatcher_MaxCapacityOnNode(1).toString()));
TestUtil.hasPauseActionForItem(queuedItem);
assertEquals(1, agent.toComputer().countBusy());
TestUtil.hasPlaceholderTaskForRun(agent, firstJobFirstRun);

Expand Down

0 comments on commit 9aee5a7

Please sign in to comment.