2017-10-17 10 views
0

Pour une exploitation forestière d'état interne dans mon pipeline jenkins J'ai créé une « carte de modèle que je veux faire usage en plusieurs étapes qui sont en cours d'exécution indépendamment en parallèleComment créer plusieurs instances d'une carte de modèle dans groovy

def status= [ 
    a : '', 
    b: [ 
      b1: '', 
      b2: '', 
      b3: '' 
     ], 
    c: [ 
     c1: '', 
     c2 : '' 
    ] 
] 

ce modèle de statut que je veux transmettre à plusieurs fonctions fonctionnant en parallèle/exécuteurs. A l'intérieur des branches parallèles que je veux modifier le statut indépendamment. Voir l'exemple minimale suivante

def status= [ 
    a : '', 
    b: [ 
     b1: '', 
     b2: '', 
     b3: '' 
    ], 
    c: [ 
     c1: '', 
     c2 : '' 
    ] 
] 

def label1 = "windows" 
def label2 = '' 


parallel firstBranch: { 
     run_node(label1, status) 
    }, secondBranch: { 
     run_node(label2, status) 
    }, 
    failFast: true|false 

def run_node (label, status){ 
    node(label) { 
     status.b.b1 = env.NODE_NAME +"_"+ env.EXECUTOR_NUMBER 
     sleep(1) 
     echo "env.NODE_NAME_env.EXECUTOR_NUMBER: ${status.b.b1}" 
     // expected: env.NODE_NAME_env.EXECUTOR_NUMBER 
     this.a_function(status) 
     echo "env.NODE_NAME_env.EXECUTOR_NUMBER: ${status.b.b1}" 
     // expected(still): env.NODE_NAME_env.EXECUTOR_NUMBER (off current node) 
     // is: env.NODE_NAME_env.EXECUTOR_NUMBERmore Info AND probably from the wrong node 
    } 
} 

def a_function(status){ 
    status.b.b1 += "more Info" 
    echo "env.NODE_NAME_env.EXECUTOR_NUMBERmore Info: ${status.b.b1}" 
    // expected: env.NODE_NAME_env.EXECUTOR_NUMBERmore Info 
    sleep(0.5) 
    echo "env.NODE_NAME_env.EXECUTOR_NUMBERmore Info: ${status.b.b1}" 
    // expected: env.NODE_NAME_env.EXECUTOR_NUMBERmore Info 
} 

qui se traduit par

[firstBranch] env.NODE_NAME_env.EXECUTOR_NUMBER: LR-Z4933-39110bdb_0

[firstBranch] env.NODE_NAME_env.EXECUTOR_NUMBERmore Info: LR-Z4933-39110bdb_0more Infos

[firstBranch] env. NODE_NAME_env.EXECUTOR_NUMBER> plus d'info: LR-Z4933-39110bdb_0more Infos

[firstBranch] env.NODE_NAME_env.EXECUTOR_NUMBER: LR-Z4933-39110bdb_0more Infos

[secondBranch] env.NODE_NAME_env.EXECUTOR_NUMBER: LR-Z4933-39110bdb_0more Infos

[secondBranch] env.NODE_NAME_env.EXECUTOR_NUMBERmore Info: LR-Z4933-39110bdb_0more Infomore Infos

[secondBranch] env. NODE_NAME_env.EXECUTOR_NUMBERmore info: LR-Z4933-39110bdb_0more Infomore Infos

[secondBranch] env.NODE_NAME_env.EXECUTOR_NUMBER: LR-Z4933-39110bdb_0more Infomore Infos

Notez que dans l'état dans la première branche est remplacé par la deuxième branche et l'inverse.

Comment réaliser des variables d'état indépendantes lors du passage thm en tant que paramètre aux fonctions

+0

Le pipeline jenkins est généré automatiquement à partir d'un fichier de configuration. il n'est donc pas possible de dire à l'avance combien d'instances du statut sont nécessaires. Dans un pipeline configuré, il peut y avoir plusieurs nœuds parallèles avec potentiellement plusieurs étages parallèles chacun. cela signifie qu'il y aura plusieurs clones du statut - un pour chaque nœud utilisé (en parallèle) pendant l'exécution du pipeline - clones du statut cloné (nœud) pour chaque étape – Ditschi

Répondre

0

Vous pouvez définir la carte du modèle. Lorsque vous avez besoin de plusieurs instances identiques, vous pouvez les modifier différemment par instance en utilisant une carte modèle clonée.

Voici un extrait de code court pour montrer l'exemple.

def template = [a: '', b: ''] 
def instancea = template.clone() 
def instanceb = template.clone() 
def instancec = template.clone() 
instancea.a = 'testa' 
instanceb.a = 'testb' 
instancec.a = 'testc' 
println instancea 
println instanceb 
println instancec 

Bien sûr, vous pouvez inclure une plus grande carte, ce qui précède est seulement pour la démonstration.

+0

y a-t-il un moyen de le faire? cloner dans une fonction? comme def my_func (a) { def = new_a a.clone() ...} – Ditschi

+0

ou autrement dit est-il un moyen de permettre une fonction à appeler plusieurs fois dans paralell sans intererence de l'autre ? – Ditschi

+0

Quel est le problème auquel vous êtes confronté? Utilisez une variable de référence (** newStatusMap **) de 'def newStatusMap = status.clone()' dans votre fonction prallel. Si vous n'en avez pas besoin, ne définissez pas de variables séparées comme ci-dessus (pour montrer l'exemple) – Rao

0

Vous transmettez status par référence à la fonction. Mais même si vous faites un status.clone(), je soupçonne que ce n'est pas une copie profonde de status. status.b pointe probablement toujours vers la même référence. Vous devez faire une copie profonde de status et envoyer cette copie profonde à la fonction. Je ne suis pas sûr qu'une copie profonde d'une carte d'infrastructure est la bonne manière de faire ceci. Vous pouvez simplement envoyer une carte vide [:] et laisser les fonctions appelées ajouter les pièces à la carte dont elles ont besoin.Si vous avez vraiment besoin de prédéfinir le contenu de la carte, alors je pense que vous devriez ajouter une classe et créer de nouveaux objets à partir de cette classe.

+0

salut j'ai converti ma carte 'status = [:]' dans une classe et ensuite appelle 'run_Node (

+0

Parce que je ne sais pas non plus que c'est la solution correcte, je ne veux pas approuver cette méthode juste par hasard J'ai aussi essayé d'ajouter Implements Clonable, puis usi ng clone() peu cela ne fonctionne pas – Ditschi