Groovy Jenkins管道@NonCPSreturn未预期结果 [英] Groovy jenkins pipeline @NonCPSreturn not expected results

查看:156
本文介绍了Groovy Jenkins管道@NonCPSreturn未预期结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中,我有一个解析日志文件并返回结果列表的方法.没有NonCPS,它可以完美工作并返回正确的值.从管道阶段调用此方法,并且得到了java.io.NotSerializableException:java.util.regex.Matcher,这就是为什么我放置@NonCPS批注的原因.不再抛出异常,但是log_parser方法不能正常工作.现在,它总是返回整个文件-即使删除return result_list.调用此方法的结果始终是文件.

    @NonCPS
    def log_parser(String filename){
    def result_list = []
    def match_f, match_s
    def lines = readFile(filename).readLines()

    for( line in lines ) {
        match_f = (line =~ /(?<=Failures: )[^ ]+/ )
        match_s = (line =~ /(?<=Skips: )[^ ]+/ )

        if( match_f ) {
            result_list[1] = (match_f[0]).replace(",", "") }
        if( match_s ) {
            result_list[2] = (match_s[0]).replace(",", "") }
    }
    return result_list
    }

解决方案

因为管道会将所有变量(包括函数内部的局部变量)序列化为默认行为,但是java.util.regex.Matcher无法序列化,所以您会收到错误消息. /p>

选项1)一旦使用完毕,立即释放不可序列化的变量.

def log_parser(String filename){
    def result_list = []
    def match_f, match_s
    def lines = readFile(filename).readLines()

    for( line in lines ) {
        match_f = (line =~ /(?<=Failures: )[^ ]+/ )
        match_s = (line =~ /(?<=Skips: )[^ ]+/ )

        if( match_f ) {
            result_list[1] = (match_f[0]).replace(",", "")
            match_f = null
        }
        if( match_s ) {
            result_list[2] = (match_s[0]).replace(",", "")
            match_s = null 
        }
    }
    return result_list
}

选项2)将不可序列化的变量移动到带有注释的函数中:@NonCPS在@NonCPS函数内部,我们无法调用任何其他管道步骤,因此应该将readFilelog_pareser()移出

log_parser(readFile(<log file path>))

@NonCPS
def log_parser(String fileContent){
    def result_list = []
    def match_f, match_s
    def lines = fileContent.readLines()

    for( line in lines ) {
        match_f = (line =~ /(?<=Failures: )[^ ]+/ )
        match_s = (line =~ /(?<=Skips: )[^ ]+/ )

        if( match_f ) {
            result_list[1] = (match_f[0]).replace(",", "") }
        if( match_s ) {
            result_list[2] = (match_s[0]).replace(",", "") }
    }
    return result_list
}

In my code I have a method that parse log file and return list of results. Without NonCPS it works perfect and return correct values. This method is called from pipeline stages and I got java.io.NotSerializableException: java.util.regex.Matcher that's why I put @NonCPS annotation. Exception is not thrown anymore but log_parser method doesnt work well. Now it always return whole file - even if remove return result_list. The result of calling this method is always file.

    @NonCPS
    def log_parser(String filename){
    def result_list = []
    def match_f, match_s
    def lines = readFile(filename).readLines()

    for( line in lines ) {
        match_f = (line =~ /(?<=Failures: )[^ ]+/ )
        match_s = (line =~ /(?<=Skips: )[^ ]+/ )

        if( match_f ) {
            result_list[1] = (match_f[0]).replace(",", "") }
        if( match_s ) {
            result_list[2] = (match_s[0]).replace(",", "") }
    }
    return result_list
    }

解决方案

Because pipeline will serialize all variables (includes local variable inside function) as default behaviour, but java.util.regex.Matcher is not serializable, that's why you get the error.

Option 1) release not serializable variable immediately once you complete using it.

def log_parser(String filename){
    def result_list = []
    def match_f, match_s
    def lines = readFile(filename).readLines()

    for( line in lines ) {
        match_f = (line =~ /(?<=Failures: )[^ ]+/ )
        match_s = (line =~ /(?<=Skips: )[^ ]+/ )

        if( match_f ) {
            result_list[1] = (match_f[0]).replace(",", "")
            match_f = null
        }
        if( match_s ) {
            result_list[2] = (match_s[0]).replace(",", "")
            match_s = null 
        }
    }
    return result_list
}

Option 2) move not serializable variables into function with annotation: @NonCPS, inside @NonCPS function, we can't call any other pipeline step, therefor you should move readFile out of log_pareser()

log_parser(readFile(<log file path>))

@NonCPS
def log_parser(String fileContent){
    def result_list = []
    def match_f, match_s
    def lines = fileContent.readLines()

    for( line in lines ) {
        match_f = (line =~ /(?<=Failures: )[^ ]+/ )
        match_s = (line =~ /(?<=Skips: )[^ ]+/ )

        if( match_f ) {
            result_list[1] = (match_f[0]).replace(",", "") }
        if( match_s ) {
            result_list[2] = (match_s[0]).replace(",", "") }
    }
    return result_list
}

这篇关于Groovy Jenkins管道@NonCPSreturn未预期结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆