Конвейер Jenkins: параллельное выполнение шагов динамически - PullRequest
1 голос
/ 28 мая 2020

В нашем конвейере Jenkins мы используем следующую функцию для выполнения набора задач развертывания в параллельных порциях:

def runParallel(tasks, count) {
    while (tasks.size() > 0) {
        parallel tasks.take(count)
        tasks = tasks.drop(count)
    }
}

С помощью параметра count мы контролируем, сколько задач выполняется параллельно, поэтому сеть не перегружена слишком большим количеством параллельных развертываний.

Это работает хорошо, но имеет обратную сторону: если одна задача в блоке занимает очень много времени, следующий блок должен ждать, пока не завершится предыдущий блок полностью закончен. Несмотря на то, что в настоящее время выполняется только одна задача и достаточно ресурсов для запуска count - 1 новых задач.

Итак, что нам действительно нужно, так это не разбивать tasks на фрагменты фиксированного размера с помощью count задач, а скорее подход со скользящим окном, который повторяет tasks с размером окна count и переходит к следующей задаче, как только первая задача внутри окна завершена. Таким образом, у нас не будет времени ожидания, которое имеет наш подход, основанный на блоках.

AFAIK невозможно добавить больше задач к шагу parallel после его запуска. Но, может быть, есть обходной путь?

В идеале parallel должен принимать параметр, который контролирует степень распараллеливания. Тогда мы могли бы просто сделать:

parallel tasks, count

1 Ответ

1 голос
/ 31 мая 2020

Кажется, вам очень повезло, так как несколько недель был выпущен плагин go, с помощью которого вы можете заархивировать это: Jenkins Concurrent Step Plugin .

Исходная проблема для этой проблемы

Пример конвейера с семафором:

pipeline {
  agent any

  stages {
    stage('test') {
      steps {
        script {
          def semaphore = createSemaphore permit: 1
          boolean out = false
          parallel(
            semaphore1: {
              acquireSemaphore (semaphore) {
                echo "out=${out}"
              }
            },
            semaphore2: {
              acquireSemaphore (semaphore) {
                sleep 30
                echo "out=${out}"
              }
            },
            semaphore3: {
              acquireSemaphore (semaphore) {
                sleep 10
                echo "out=${out}"
              }
            },
            semaphore4: {
              acquireSemaphore (semaphore) {
                sleep 10
                echo "out=${out}"
              }
            }
          )
        }
      }
    }
  }
}
...