我在Jenkinsfile中发现了Groovy代码的一个奇怪问题:
@NonCPS
def test() {
println "Start"
sleep(10)
println "Stop"
}
事实是,睡眠10秒钟之后,代码再也无法进入println "Stop"
。
看来,睡眠会在10秒后返回并运行下一个管道步骤。
输出就是:
[Pipieline] echo
Start
[Pipeline] sleep
Sleeping for 10 sec
[Pipeline] }
... next pipeline steps
有人有同样的问题吗?
答案 0 :(得分:2)
当您在Groovy脚本中调用IE.document
时,Workflow CPS插件将执行SleepStep
而不是DefaultGroovyStaticMethods.sleep(Object self, long time)
。您遇到的问题是由sleep(10)
函数引起的(感谢mkobit的建议!)。考虑以下示例:
@NonCPS
输出:
node {
stage("Test") {
test()
}
}
@NonCPS
def test() {
echo "Start"
sleep(5)
echo "Stop"
}
管道运行中没有回显[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/test-pipeline
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] echo
Start
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
。现在,如果仅从我们在管道中调用的函数中删除Stop
批注:
@NonCPS
事情变了,node {
stage("Test") {
test()
}
}
def test() {
echo "Start"
sleep(5)
echo "Stop"
}
得到了预期的回响:
Stop
有关使用Started by user admin
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/test-pipeline
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] echo
Start
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] echo
Stop
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
的更多信息,请阅读以下Best Practices For Pipeline Code文章。
答案 1 :(得分:0)
此问题在https://wiki.jenkins.io/display/JENKINS/Pipeline+CPS+method+mismatches
中有详细记录使用@NonCPS中的管道步骤
有时,用户会将@NonCPS注释应用于方法定义,从而绕过该方法内部的CPS转换。可以这样做来解决Groovy语言覆盖范围的局限性(因为该方法的主体将使用本地Groovy语义执行),或获得更好的性能(解释器会带来相当大的开销)。但是,此类方法不得调用经过CPS转换的代码,例如管道步骤。
如Szymon所建议,删除@NonCPS标记确实可以解决此问题, 但是,如果由于需要它而不能删除@NonCPS标记(例如,解决序列化问题),则可以通过使用Thread.sleep(long millis) Java方法来克服。
通知-如果在沙箱中运行,管理员将需要批准此签名。