我正在構建一個Jenkins作業,它將一直運行我所有的分段測試,但不是一次全部(它們都依賴於共享硬件)。所以,我創建了並行作業,並使用信號量來確保只有有限的數量一次運行。 這裏是我的管道再現問題的簡化版本:Jenkins管道和信號燈
import java.util.concurrent.Semaphore
def run(job) {
return {
this.limiter.acquire();
try {
println "running ${job}"
build job
println "finished ${job}"
} finally {
this.limiter.release();
}
}
}
def getJobs() {
def allJobs = Jenkins.getInstance().getJobNames()
def stagingJobs = []
for(String job : allJobs) {
if (job.startsWith("staging/temp")) {
stagingJobs.add(job)
}
}
println "${stagingJobs.size()} jobs were found."
return stagingJobs
}
this.limiter = new Semaphore(2)
def jobs = [:]
for (job in getJobs()) {
jobs[job] = run(job)
}
parallel jobs
當我沒有信號燈運行,一切正常。但上面的代碼中,我得到不同的輸出什麼:
[Pipeline] echo
6 jobs were found.
[Pipeline] parallel
[Pipeline] [staging/temp1] { (Branch: staging/temp1)
[Pipeline] [staging/temp2] { (Branch: staging/temp2)
[Pipeline] [staging/temp3] { (Branch: staging/temp3)
[Pipeline] [staging/temp4] { (Branch: staging/temp4)
[Pipeline] [staging/temp5] { (Branch: staging/temp5)
[Pipeline] [staging/temp6] { (Branch: staging/temp6)
如果我查看管道的步驟,我可以看到前兩個作業啓動,它們的日誌信息輸出。但是,似乎跑步者從未收到關於登臺作業完成的通知。結果,信號量從未釋放,其他4個工作從未開始。這裏有一個線程轉儲中期試驗中,下游的建立有一定結束後:
Thread #7
at DSL.build(unsure what happened to downstream build)
at WorkflowScript.run(WorkflowScript:9)
at DSL.parallel(Native Method)
at WorkflowScript.run(WorkflowScript:38)
Thread #8
at DSL.build(unsure what happened to downstream build)
at WorkflowScript.run(WorkflowScript:9)
Thread #11
at WorkflowScript.run(WorkflowScript:6)
Thread #12
at WorkflowScript.run(WorkflowScript:6)
最終超時幾個java.lang.InterruptedException
錯誤。
是否有可能在流水線中使用信號燈,還是有更好的方法來確保只有一部分工作同時運行?我寧願避免爲了簡單的測試跑步者而轉動節點。
的說明給他人:傑西·格里克指出這對詹金斯JIRA:「你可以不使用來自管道腳本本地Java併發原語 - 它運行在單線程虛擬機中「 – Crummy