Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-18536

Remove downstream job from queue before new triggers

      Given two jobs:

      • Downstream, which has a 60s quiet period
      • Upstream, which triggers a parameterized build on Downstream

      Now, if you quickly trigger Upstream 3 times, then there will be 3 Downstream jobs in the queue. They will then all run.

      We would like parameterized triggering in combination with downstream quiet period to behave sort of like the SVN quiet period behaves: If Upstream is triggered multiple times, then only the last triggered Downstream will remain in the queue. This will help when you have limited verification resources during development and would like to run a "best effort" approach. It will prevent the queue from continuously growing.

      Summary: Before Upstream triggers Downstream, Upstream should remove any instances of Downstream from the queue. This should of course be an option and not the default behavior.

          [JENKINS-18536] Remove downstream job from queue before new triggers

          Markus added a comment -

          For anyone that may need the same feature. Our current work-around is a rather messy groovy script added to Upstream:

          CancelDownstreamQueue.groovy
          import hudson.model.*
          
          Jenkins = Hudson.instance
          def q = Jenkins.instance.queue;
          
          if ( args.length != 2 ) {
            println "ERROR - CancelDownstreamQueue.groovy - Scripts needs two arguments. Own job name and part of downstream job name to search for. Do not know if wildcards are supported." 
          } else {
            println("Search for downstream jobs from " + args[0] + " whose name contains " + args[1]);
            def thisjob = Jenkins.getInstance().getItemByFullName(args[0]);
            if (thisjob == null) {
              println("ERROR - CancelDownstreamQueue.groovy - Could not find this job");
            }else{  
              //println(thisjob.getDownstreamProjects())
              List<AbstractProject> childs = thisjob.getDownstreamProjects()
              if (childs == null) {
               println("ERROR - CancelDownstreamQueue.groovy - childs is null");
              }else{
                for (Iterator<AbstractProject> iterator = childs.iterator(); iterator.hasNext();) {
                  AbstractProject child = iterator.next();
                  if (child.getFullName().contains(args[1])) {
                    println("  Found downstream job " + child.getFullName() + ". Searching for queued items");
                    q.items.findAll { it.task.name.equals(child.getFullName()) }.each {
                      println("    Cancelling queued " + it.task.getDisplayName());
                      q.cancel(it.task);
                    }
                  } else {
                    println("  Skipping " + child.getFullName());
                  }
                }
              }
            }
            println("Done");
          }
          

          But the script is not 100% stable. It happens to fail (hangs or generates a java.lang.NegativeArraySizeException).
          The script is started like this:

          java -jar jenkins-cli.jar -s http://jenkins:8080/ groovy ./CancelDownstreamQueue.groovy $JOB_NAME SearchStringForJobsToCancel
          

          Markus added a comment - For anyone that may need the same feature. Our current work-around is a rather messy groovy script added to Upstream: CancelDownstreamQueue.groovy import hudson.model.* Jenkins = Hudson.instance def q = Jenkins.instance.queue; if ( args.length != 2 ) { println "ERROR - CancelDownstreamQueue.groovy - Scripts needs two arguments. Own job name and part of downstream job name to search for . Do not know if wildcards are supported." } else { println( "Search for downstream jobs from " + args[0] + " whose name contains " + args[1]); def thisjob = Jenkins.getInstance().getItemByFullName(args[0]); if (thisjob == null ) { println( "ERROR - CancelDownstreamQueue.groovy - Could not find this job" ); } else { //println(thisjob.getDownstreamProjects()) List<AbstractProject> childs = thisjob.getDownstreamProjects() if (childs == null ) { println( "ERROR - CancelDownstreamQueue.groovy - childs is null " ); } else { for (Iterator<AbstractProject> iterator = childs.iterator(); iterator.hasNext();) { AbstractProject child = iterator.next(); if (child.getFullName().contains(args[1])) { println( " Found downstream job " + child.getFullName() + ". Searching for queued items" ); q.items.findAll { it.task.name.equals(child.getFullName()) }.each { println( " Cancelling queued " + it.task.getDisplayName()); q.cancel(it.task); } } else { println( " Skipping " + child.getFullName()); } } } } println( "Done" ); } But the script is not 100% stable. It happens to fail (hangs or generates a java.lang.NegativeArraySizeException). The script is started like this: java -jar jenkins-cli.jar -s http: //jenkins:8080/ groovy ./CancelDownstreamQueue.groovy $JOB_NAME SearchStringForJobsToCancel

            huybrechts huybrechts
            mabahj Markus
            Votes:
            5 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated: