2017-05-30 142 views
2

我正在构建一个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错误。

是否有可能在流水线中使用信号灯,还是有更好的方法来确保只有一部分工作同时运行?我宁愿避免为了简单的测试跑步者而转动节点。

+0

的说明给他人:杰西·格里克指出这对詹金斯JIRA:“你可以不使用来自管道脚本本地Java并发原语 - 它运行在单线程虚拟机中“ – Crummy

回答

1

由于每年至少有一个插件,它会帮助你得到你的意图是什么,有也使用这个插件流水线作业的选项,这个插件是Lockable Plugin Resource

基本上你换你的共享资源和如果资源不空闲,作业将在锁定语句之前排队。

如果你有兴趣在并行你的测试,你也可以看看Parallel Test Executor Plugin

+0

有没有办法让一个可锁定的资源允许X simulatenous锁? – Crummy

+0

我以前没做过,但我认为你应该用相同的标签(不同的名字)来定义各种资源。当你锁定一个资源时,你应该用你需要的特定标签来指定资源的数量。这样你就可以获得各种资源,每项工作都会锁定你想要的资源数量。 – jperis