Déclaration parallèle de Powershell Workflow Variables partagées

J'ai de la difficulté à comprendre pourquoi le code ci-dessous se comporte comme il est. J'ai fait de nombreuses recherches dans Google et StackOverflow et ne trouve rien qui semble indiquer une solution pour cela.

Dans un Runbook Azure Automation, j'essaie d'exécuter la même activité avec différents paramètres dans un bloc Parallel. J'ai réussi à affiner le problème jusqu'aux blocs de construction de base et cela se passe dans Powershell Workflow sans Azure impliqué.

Quand j'exécute ce code dans Powershell, la sortie semble être piétinée et le hasard s'ensuit. Cela a pour conséquence que mes activités de workflow modulaires se comportent mal.

Si je cours cette même section de code en dehors d'un bloc parallèle (avec ou sans bloc de séquence) cela fonctionne bien. (Vous pouvez voir les blocs commentés dans le code ci-dessous).

L'autre chose que j'ai remarquée est que si je n'ai pas la 3ème activité de workflow impliquée, le parallèle fonctionne bien (si seulement il définit la valeur directement au lieu d'utiliser la valeur de sortie du 3ème workflow).

Cependant, une fois que Test appelle TestChild appelle TestGetLocationValue, le bloc parallèle renvoie les résultats aléatoires et inattendus.

Quelqu'un peut-il expliquer s'il vous plaît:

  1. Pourquoi le comportement se produit-il?
  2. Qu'est-ce qu'une solution de contournement/correctif pour permettre à cela de fonctionner correctement?

Voici la sortie d'un couple de courses:

Run One PS U:> Test

Name                           Value                                                                                                                                                                                                                             
----                           -----                                                                                                                                                                                                                             
Tag                            P4                                                                                                                                                                                                                                
Location                       {Hi, LP4, System.Collections.Hashtable}                                                                                                                                                                                           
Tag                            P5                                                                                                                                                                                                                                
Location                       Hi, LP5                                                                                                                                                                                                                           
Tag                            P6                                                                                                                                                                                                                                
Location                       Hi, LP6  

Run Two PS U:> Test

Name                           Value                                                                                                                                                                                                                             
----                           -----                                                                                                                                                                                                                             
Tag                            P1                                                                                                                                                                                                                                
Location                       Hi, LP1  

Run Three (With Verbose, Note the "HashTable" references)

PS U:\> Test -Verbose
VERBOSE: [localhost]:Parallel Run:
VERBOSE: [localhost]:[P2] Location before call: ''
VERBOSE: [localhost]:[P1] Location before call: ''
VERBOSE: [localhost]:[P4] Location before call: ''
VERBOSE: [localhost]:[P3] Location before call: ''
VERBOSE: [localhost]:[P5] Location before call: ''
VERBOSE: [localhost]:[P6] Location before call: ''
VERBOSE: [localhost]:[P7] Location before call: ''
VERBOSE: [localhost]:[P8] Location before call: ''
VERBOSE: [localhost]:[P9] Location before call: ''
VERBOSE: [localhost]:[P2] Location after call: 'Hi, LP2'

Name                           Value                                                                                                                                                                                                                             
----                           -----                                                                                                                                                                                                                             
Tag                            P2                                                                                                                                                                                                                                
Location                       Hi, LP2                                                                                                                                                                                                                           
VERBOSE: [localhost]:[P3] Location after call: 'Hi, LP3'
VERBOSE: [localhost]:[P1] Location after call: 'Hi, LP1'
VERBOSE: [localhost]:[P4] Location after call: 'Hi, LP4 System.Collections.Hashtable'
VERBOSE: [localhost]:[P6] Location after call: 'Hi, LP6 System.Collections.Hashtable'
VERBOSE: [localhost]:[P5] Location after call: 'Hi, LP5 System.Collections.Hashtable'
VERBOSE: [localhost]:[P8] Location after call: 'Hi, LP8'
VERBOSE: [localhost]:[P7] Location after call: 'Hi, LP7'
VERBOSE: [localhost]:[P9] Location after call: 'Hi, LP9'
VERBOSE: [localhost]:[Test] Location Value After Parallel (Proves that Location doesn't leak to root workflow): ''

Bloc de code (Test.ps1)

workflow TestGetLocationValue
{
    param
    (
        $tag
    )

    $myLocation = "Hi, $tag"
    Write-Output $myLocation
}

workflow TestChild
{
    param
    (
        $tag
    )

    <#Write-Verbose "[$tag] MyLocation before call (Proves that mylocation doesn't leak to testchild workflow): '$myLocation'"#>
    Write-Verbose "[$tag] Location before call: '$location'"
    $location = TestGetLocationValue -tag "L$tag"
    <# This works: $location = "Hi, $tag" #>
    Write-Verbose "[$tag] Location after call: '$location'"
    <#Write-Verbose "[$tag] MyLocation after call Value (Proves that mylocation doesn't leak to testchild workflow): '$myLocation'"#>

    Write-Output @{
        Tag = $tag
        Location = $location
    }
}

workflow Test
{
    $location = $null

    <#
    Write-Verbose "Normal Run:"
    TestChild -tag "N1"
    TestChild -tag "N2"
    TestChild -tag "N3"
    TestChild -tag "N4"
    TestChild -tag "N5"
    TestChild -tag "N6"
    TestChild -tag "N7"
    TestChild -tag "N8"
    TestChild -tag "N9"
    Write-Verbose "[Test] Location Value After Normal (Proves that Location doesn't leak to root workflow): '$location'"
    #>

    Write-Verbose "Parallel Run:"
    Parallel
    {
        TestChild -tag "P1"
        TestChild -tag "P2"
        TestChild -tag "P3"
        TestChild -tag "P4"
        TestChild -tag "P5"
        TestChild -tag "P6"
        TestChild -tag "P7"
        TestChild -tag "P8"
        TestChild -tag "P9"
    }
    Write-Verbose "[Test] Location Value After Parallel (Proves that Location doesn't leak to root workflow): '$location'"

    <#
    Write-Verbose "Sequence Run:"
    Sequence
    {
        TestChild -tag "S1"
        TestChild -tag "S2"
        TestChild -tag "S3"
        TestChild -tag "S4"
        TestChild -tag "S5"
        TestChild -tag "S6"
        TestChild -tag "S7"
        TestChild -tag "S8"
        TestChild -tag "S9"
    }
    Write-Verbose "[Test] Location Value After Sequence (Proves that Location doesn't leak to root workflow): '$location'"
    #>
}
0
Changer TestGetLocationValue en: workflow TestGetLocationValue {param ($ tag) "Salut, $ tag"} ne semble pas aider le cas.
ajouté l'auteur Alan Wood, source
Il semble tout à fait probable que la question soit ici en quelque sorte. La routine consiste essentiellement à définir une valeur et à la renvoyer à l'appelant. (Write-Output est la méthode pour renvoyer des valeurs dans la mesure où je comprends Powershell et est marquée comme s'exécutant localement seulement dans la documentation de workflow).
ajouté l'auteur Alan Wood, source
Que se passe-t-il dans TestGetLocationValue ? Il est possible que cette fonction ne soit pas thread-safe.
ajouté l'auteur Vesper, source

Il n'y a pas de réponses.

0