4141import org .jenkinsci .plugins .workflow .graph .StepNode ;
4242import org .jenkinsci .plugins .workflow .graphanalysis .LinearBlockHoppingScanner ;
4343import org .jenkinsci .plugins .workflow .steps .StepDescriptor ;
44+ import org .jenkinsci .plugins .workflow .support .actions .PauseAction ;
4445import org .jenkinsci .plugins .workflow .support .concurrent .Timeout ;
4546import 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}
0 commit comments