我正在执行并行步骤 -
> tapply(df$samp.45, as.factor(df$group), mean)
1 2 3
78.19556 79.65747 68.91818
现在我需要在C完成后开始执行B.我可以将B作业拉出并行块并在并行块之后添加以实现此目的。但在这种情况下,在A和C完成之前,B不会启动。对于长时间的A作业,当您有可用的空闲构建服务器时,这会影响性能。 我们是否可以解决/改进执行计划以并行运行所有计划,但使用“依赖关系”'或者'优先事项'用于并行步骤。 Promotions插件中存在类似的机制,但需要在管道中实现。
答案 0 :(得分:2)
您绝对可以。尝试这样的事情:
stages {
stage ('Parallel build LEVEL 1 - A/C+B ...') {
parallel {
stage("Build A") {
agent { node { label 'A'}}
steps {
buildAndArchive(A)
}
}
stage("Build C and B") {
stages {
stage("Build C") {
agent { node { label 'C'}}
steps {
buildAndArchive(C)
}
}
stage("Build B") {
agent { node { label 'B'}}
steps {
buildAndArchive(B)
}
}
}
这将并行执行两个分支,其中一个分支在构建A,另一个在先构建C,然后在B。
另请参阅https://jenkins.io/blog/2018/07/02/whats-new-declarative-piepline-13x-sequential-stages/
答案 1 :(得分:0)
使B在C之后执行:
parallel (
"Build A": {
node('Build_Server_Stack') {
buildAndArchive(A) // my code
}
},
"Build C then B" : {
node('Build_Server_Stack') {
buildAndArchive(C)
buildAndArchive(B)
}
}
)
...这不是很有趣。
一个更有趣的情况是,当您有4个作业(A,B,C和D),其中C仅取决于A,而D取决于A和B时,像这样:
A B
| \ |
C D
使这个变得有趣的是,您不能直接在Jenkins管道中表达这一点。无论您如何将作业安排在不同的并行块中,都将始终强制一项作业不必要地等待另一项。 您可以合理地将工作安排为:
[A, B]
[C, D]
但是,即使A快速完成,C也需要等待B。
或者:
[A]
[C, B+D]
但是现在D必须等待A和B串联。
大概大多数人将有足够的信息来选择“足够好”的配置,但是不幸的是,詹金斯似乎对此没有通用的解决方案。 It's not like this is a new idea。
要解决此问题,我同时运行所有并行线程,然后让它们每个依次轮流等待其依赖关系。像CountDownLatch之类的东西将是实现等待的完美解决方案,但这对Jenkins来说并不是很好。 waitUntil
Jenkins步骤似乎很理想,但是由于它是基于民意测验的,因此在完成工作和waitUntil
注意之间不可避免地会有延迟。另一方面,lock
的行为就像互斥锁。通过将两者结合起来,我们可以获得一项工作所需的行为,该行为几乎在其依赖关系完成后立即开始。
// Map job name to the names of jobs it depends on.
jobDependencies = [
"A": [],
"B": [],
"C": ["A"],
"D": ["A", "B"]
]
lockTaken = [:]
threads = [:]
jobDependencies.each { name, dependencies ->
threads[name] = {
// Use a lock with a name unique to this build.
lock("${name}-${BUILD_TAG}") {
// Notify other threads that the lock has been taken and it's safe to wait on it.
lockTaken[name] = true
dependencies.each { dependency ->
// Poll until the dependency takes its lock.
waitUntil {
lockTaken[dependency]
}
// Wait for the dependency to finish and release its lock.
lock("${dependency}-${BUILD_TAG}") {}
}
// Actually run the job
buildAndArchive(name)
}
}
}
parallel threads
尽管感觉好像必须有更好的解决方案,但效果很好。我希望通过提供此答案,有人会注意到,或者a)告诉我我错了,并指出正确的答案;或b)制作一个插件来正确执行;)