Hi All,

Thank you for answers. Finally I found correct way. Only map.sort was necessary move under @NonCPS function.
My work pipeline looks:


def behatList =['AutoSuiteSet_0', 'AutoSuiteSet_1', 'AutoSuiteSet_2', 'AutoSuiteSet_3', 'AutoSuiteSet_4', 'AutoSuiteSet_5'] def suitesStat=[AutoSuiteSet_0:0, AutoSuiteSet_1:1, AutoSuiteSet_2:2, AutoSuiteSet_3:3, AutoSuiteSet_4:4, AutoSuiteSet_5:5]

stage("test") {
    node('master') {
behatList2=sortSuites(behatList, suitesStat)
        echo "SUITES2=${behatList2}"
    }
}

def sortSuites(suites, suites_time){
    def suitesMap = [:]
    if (suites_time.size()>0){
        timeLimit = suites_time.values().max()
        for(s in suites){
          x = suites_time.find{ artifact -> artifact.key == s}
          if(x){
            suitesMap.put(x.key, x.value)
          }else{
            suitesMap.put(s, timeLimit)
          }
        }
    }else{
        suitesList = suites.collect { t -> [t] }
        return suitesList
    }
    tasks = divideList(suitesMap)
    tasks = sortListInMap(tasks)
    tasksList = tasks.collect { t -> t.keySet()}
    return tasksList
}

def divideList(inputMap){
    inputMap=sortMap(inputMap)
    maxValue = inputMap.values().max()
    def outputSet = []
    def outputMap = [:]
    for (inputElement in inputMap) {
       possibleMap = outputMap + [inputElement]
       possibleMapSum = possibleMap.values().sum()
       if (possibleMapSum < maxValue) {
           outputMap = possibleMap
       }else if(possibleMapSum == maxValue) {
           outputSet.add(possibleMap)
           outputMap = [:]
       }else if(possibleMapSum > maxValue) {
           outputSet.add(outputMap)
           outputMap = [:]
           outputMap.put(inputElement.key, inputElement.value)
       }
    }
    if (outputMap) {
       outputSet.add(outputMap)
    }
    return outputSet
}

@NonCPS
def sortMap(map) {
  map.sort{a, b -> b.value <=> a.value }
}

@NonCPS
def sortListInMap(map) {
    map.sort { a, b -> b.values().sum() <=> a.values().sum() }
}




06.08.2017 17:47, Michael Pailloncy пишет:
It seems like there are some variables used out of their scope and some misused Groovy methods.

Here is a working version, IIUC your pipeline :-)

#!groovy

def behatList =['AutoSuiteSet_0', 'AutoSuiteSet_1', 'AutoSuiteSet_2', 'AutoSuiteSet_3', 'AutoSuiteSet_4', 'AutoSuiteSet_5'] def suitesStat=[AutoSuiteSet_0:0, AutoSuiteSet_1:1, AutoSuiteSet_2:2, AutoSuiteSet_3:3, AutoSuiteSet_4:4, AutoSuiteSet_5:5]

stage("test") {
node('master') {
    behatList2=sortSuites(behatList, suitesStat)
    echo "SUITES2=${behatList2}"
}
}

@NonCPS
def sortSuites(suites, suites_time){
def timeLimit = suites_time.values().max()
def suitesMap= [:]
for(s in suites){
    def x = suites_time.find{ artifact -> artifact.key == s}
if(x){
        suitesMap.put(x.key, x.value)
    }else{
        suitesMap.put(s, timeLimit)
    }
}
def tasks = [suitesMap]
timeLimit = suitesMap.values().max()
while(canSplit(tasks, timeLimit)) {
    tasks = tasks.collect { t ->
if(checkLimit(t, timeLimit)){
            t = splitTo2(t)
        }
        t
    }.flatten()
}
tasks.sort { a, b -> b.values().sum() <=> a.values().sum() }
// tasks = tasks.collect { t -> t.keySet()} // not working, multiple elements are collected here
tasks = tasks.collectMany { t -> t.keySet()}
return tasks
}


@NonCPS
def checkLimit(t, timeLimit) {
if(t.values().sum()>timeLimit && t.size()>1){
return true
}else{
return false
}
}

@NonCPS
def canSplit(tasks, timeLimit) {
for(t in tasks) {
if(checkLimit(t, timeLimit)){
return true
  }
  }
return false
}


@NonCPS
def splitTo2(int_map) {
A=[:]
B=[:]

// int_map.sort{it.value} not working
// for(n in int_map.sort{it.value}) {
for(n in int_map) {
if (A.size() < B.size()) {
        A.put(n.key, n.value)
    }else{
        B.put(n.key, n.value)
    }
}
return [A, B]
}


However, what do you want to achieve exactly ? One of the main advantage of Pipeline is its resumability after restart. But if you use too many @NonCPS, you avoid this feature and this could lead to unexpected behaviour sometimes.

Hopefully it helps :-)


2017-08-04 19:17 GMT+02:00 Slava Dubrovskiy <[email protected] <mailto:[email protected]>>:

    Hi.

    I use a special algorithm to pre-sort the steps for parallel start.
    Here is my test pipeline:

    |
    #!groovy

    defbehatList
    
=['AutoSuiteSet_0','AutoSuiteSet_1','AutoSuiteSet_2','AutoSuiteSet_3','AutoSuiteSet_4','AutoSuiteSet_5']
    
defsuitesStat=[AutoSuiteSet_0:0,AutoSuiteSet_1:1,AutoSuiteSet_2:2,AutoSuiteSet_3:3,AutoSuiteSet_4:4,AutoSuiteSet_5:5]

    stage("test"){
        node('master'){
            behatList2=sortSuites(behatList,suitesStat)
            echo "SUITES2=${behatList2}"
    }
    }

    @NonCPS
    defsortSuites(suites,suites_time){
        timeLimit =suites_time.values().max()
    defsuitesMap=[:]
    for(s insuites){
            x=suites_time.find{artifact ->artifact.key ==s}
    if(x){
                suitesMap.put(x.key,x.value)
    }else{
                suitesMap.put(s,timeLimit)
    }
    }
        tasks =[suitesMap]
        timeLimit =suitesMap.values().max()
    while(canSplit()){
            tasks =tasks.collect {t ->
    if(checkLimit(t)){
                    t =splitTo2(t)
    }
                t
    }.flatten()
    }
        tasks.sort {a,b ->b.values().sum()<=>a.values().sum()}
        tasks =tasks.collect {t ->t.keySet()}
    returntasks
    }


    @NonCPS
    defcheckLimit(t){
    if(t.values().sum()>timeLimit &&t.size()>1){
    returntrue
    }else{
    returnfalse
    }
    }

    @NonCPS
    defcanSplit(){
    for(t intasks){
    if(checkLimit(t)){
    returntrue
    }
    }
    returnfalse
    }


    @NonCPS
    defsplitTo2(int_map){
        A=[:]
        B=[:]
    for(n inint_map.sort{it.value}){
    if(A.size()<B.size()){
                A.put(n.key,n.value)
    }else{
                B.put(n.key,n.value)
    }
    }
    return[A,B]
    }

    |


    If I run it, I get the error:
    |
    an exception which occurred:
    infield delegate
    infield closures
    inobjectorg.jenkinsci.plugins.workflow.cps.CpsThreadGroup@7fd2cde1
    Caused:java.io.NotSerializableException:java.util.LinkedHashMap$Entry
     at
    
org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
     at
    
org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
     at
    
org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
     at
    
org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOu
    ...
    |

    Please, help me what is wrong?
    All methods under @NonCPS directive.

    --
    WBR,
    Slava.
-- You received this message because you are subscribed to the Google
    Groups "Jenkins Users" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to [email protected]
    <mailto:[email protected]>.
    To view this discussion on the web visit
    
https://groups.google.com/d/msgid/jenkinsci-users/e7a79c56-512f-4706-ab65-9a347966abb3%40googlegroups.com
    
<https://groups.google.com/d/msgid/jenkinsci-users/e7a79c56-512f-4706-ab65-9a347966abb3%40googlegroups.com?utm_medium=email&utm_source=footer>.
    For more options, visit https://groups.google.com/d/optout
    <https://groups.google.com/d/optout>.


--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected] <mailto:[email protected]>. To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/CAPO77c0_uu7GwQGL3GNGoyh-D878mrbiMj-1fUZefgN0bRPmsA%40mail.gmail.com <https://groups.google.com/d/msgid/jenkinsci-users/CAPO77c0_uu7GwQGL3GNGoyh-D878mrbiMj-1fUZefgN0bRPmsA%40mail.gmail.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

--
WBD,
Viacheslav Dubrovskyi

--
You received this message because you are subscribed to the Google Groups "Jenkins 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jenkinsci-users/19b4ba24-82ea-a925-12c5-a82528816e21%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to