Buildbot: рабочий простаивает

#python #python-3.x #triggers #buildbot

#python #python-3.x #триггеры #buildbot

Вопрос:

Я заметил, что распределение сборок между рабочими неоптимально, 80% времени сборки выполняются на занятых рабочих.

Если вы посмотрите на изображение, tmp_worker1 можете обработать triggered_build_1 , но вместо этого он простаивает!!! По какой-то причине triggered_build_1 находится в заблокированном состоянии и назначается занятому example-worker

введите описание изображения здесь

У меня следующая настройка:

  • 3 рабочих
  • 1 главный конструктор
  • 3 запускаемых компоновщика (с блокировками)

Основной исходный код ниже

 # triggerable scheduler
c['schedulers'].append(schedulers.Triggerable(name="trigger_from_main",
    builderNames=['triggered_build_0', 'triggered_build_1', 'triggered_build_2']))

# main builder factory
factory_main = util.BuildFactory()

# trigger
factory_main.addStep(steps.Trigger(
    schedulerNames=['trigger_from_main'],
    waitForFinish=True,
    haltOnFailure=True,
    name='trigger'
))

# main builder 
c['builders'].append(
    util.BuilderConfig(name="test_main",
        workernames=['example-worker', 'tmp_worker0', 'tmp_worker1'],
        factory=factory_main,
    )
)

# lock
worker_lock = [util.WorkerLock("worker_builds", maxCount=1).access('counting')]

# 1st of 3 sub-builder
c['builders'].append(
    util.BuilderConfig(name="triggered_build_0",
        workernames=['example-worker', 'tmp_worker0', 'tmp_worker1'],
        factory=factory_subbuild,
        locks=worker_lock,
    )
)

# 2nd of 3 sub-builder
...
# 3rd of 3 sub-builder
...
  

Комментарии:

1. Я думаю, вам нужно будет предоставить больше вашего кода, достаточно, чтобы мы могли создать рабочую реплику и попытаться решить ваш вопрос

Ответ №1:

Такое поведение вызвано блокировками и способом распространения сборки мастером.

Когда необходимо запустить сборку, мастер выполняет следующий шаг (ссылка на исходный код):

  • Случайным образом выбирается рабочий
  • Проверьте, совпадают ли рабочий и сборка
  • Проверьте, может ли сборка принимать блокировки, необходимые для рабочего
  • Назначьте сборку мастеру

И когда сборка начинается на рабочем, он получает блокировку.

Поэтому, если мастер проверяет требование отправки следующей сборки до получения блокировки, он может отправить новую сборку тому же рабочему (даже если им нужна одна и та же блокировка).

Это можно исправить, если поместить в карантин рабочий, которому назначена сборка, чтобы дать рабочему достаточно времени для снятия блокировки. Вы можете сделать это с canStartBuild помощью функции, которая запускается непосредственно перед назначением сборки рабочему (docs).

 def canStartBuildLockQuarantine(builder, wfb, request):
    # Put the worker in quarantine for 5 seconds
    wfb.worker.quarantine_timeout = 5
    wfb.worker.putInQuarantine()
    # Reset wfb.worker.quarantine_timeout
    wfb.worker.resetQuarantine()
    return True
  

И передайте его рабочему, который будет принимать блокировки.

 c['builders'].append(
    util.BuilderConfig(name="triggered_build_0",
        workernames=['example-worker', 'tmp_worker0', 'tmp_worker1'],
        factory=factory_subbuild,
        canStartBuild=canStartBuildLockQuarantine,
        locks=worker_lock,
    )
)
  

Комментарии:

1. Вау!!! Это работает идеально. Большое спасибо за вас. Даже сообщество buildbot на github не помогло с этой проблемой