Выполнение заданий Powershell правильно обрабатывает пакет, не дожидаясь его завершения - PullRequest
0 голосов
/ 28 апреля 2018

Я использую работу PowerShell для параллельной обработки действий. Я приложил образец кода ниже.

Function Wait-UntilJobFailOrSuccess {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.Job[]]$Job
    )
    begin {
        $jobs = @()
        $abort = $false
    }
    process {
        $jobs += $Job
    }
    end {

        while ('Running' -In $jobs.State) {
            if ('Failed' -in $jobs.State) {
                $jobs | Stop-Job 
                $abort = $true
                break
            }
            Start-Sleep -Milliseconds 500
        }

        foreach ($job in $jobs) {
            if ($job.State -eq 'Failed') {
                $job.ChildJobs | ForEach-Object {
                    Write-Host ($_.JobStateInfo.Reason.Message) -ForegroundColor Red
                }
            }
            else {

                Write-Host "$($job.Name) $($job.State) successfully"
            }
        }

        if ($abort) {
            exit 1
        }
    }
}

Вышеуказанный метод будет использоваться для задания, которое будет выполняться параллельно.

$packageSpecs | ForEach-Object -Begin {
    $job = @()
} -Process {
    $builditem = $_ 
   $job += Start-Job -Name $("Pack" + $builditem.name) -ScriptBlock $scriptoExecute -ArgumentList $args
    if ($job.Count -eq $maxNumberOfThread) {
        $job |Wait-UntilJobFailOrSuccess
        $job = @()
    }
} -End {

    if ($job.Count -gt 0) {
        $job |Wait-UntilJobFailOrSuccess
        $job = @()
    }

}

Если вы видите код выше, я запускаю задание на основе количества процессоров, присутствующих в машине, $ maxNumberOfThread содержит число логических процессов, разрешенных в системе.

Теперь я расскажу вам о своей проблеме.

Предположим, $ maxNumberOfThread = 4. Он будет обрабатывать 4 задания одновременно. То, что я хочу, - это если я обрабатываю 4 задания, и любое задание выполнено. Я должен быть в очереди на следующий. В настоящее время он обрабатывает все 4 задания, затем следующую партию.

1 Ответ

0 голосов
/ 28 апреля 2018

Я сделал несколько настроек, я отключил функцию Wait-tillJobFailOrSuccess. Но это должно работать. Попробуй и дай мне знать. Если он работает, то вы можете настроить его для своей функции.

 $packageSpecs | ForEach-Object -Begin {
     $job = @()
 } -Process {
     $builditem = $_ 
     $job += Start-Job -Name $("Pack" + $builditem.name) -ScriptBlock $scriptoExecute -ArgumentList $args
     $running = @($job | Where-Object { $_.State -eq 'Running' })
     if ($running.Count -ge $maxNumberOfThread) {
         $running | Wait-Job -Any | Out-Null
         Write-Verbose "Waiting on jobs" -Verbose
     }  

 } -End {

     if ($job.Count -gt 0) {
         $job |Wait-UntilJobFailOrSuccess
         $job = @()
     }
 }

Я сделал некоторые изменения в вашей функции, пожалуйста, дайте мне знать, как это работает. Теперь функции нужно передать $ MaxNumberOfThread.

Function Wait-UntilJobFailOrSuccess {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.Job[]]$Job,

        [Parameter()]
        [int]$maxNumberOfThread
    )
    begin {
        $jobs = @()
        $abort = $false
    }
    process {
        $jobs += $Job
        foreach ($j in $Jobs) {
            $running = @($jobs | Where-Object { $_.State -eq 'Running' })
            if ($running.Count -ge $maxNumberOfThread) {
                if ('Failed' -in $jobs.State) {
                    $jobs | Stop-Job 
                    $abort = $true
                    break
                }
                else {
                    $running | Wait-Job -Any | Out-Null
                    Write-Verbose "Waiting on jobs" -Verbose
                }
            }
            if ($abort) {
                exit 1
            }
        }
    }
    end {
        foreach ($j in $jobs) {
            if ($j.State -eq 'Failed') {
                $j.ChildJobs | ForEach-Object {
                    Write-Host ($_.JobStateInfo.Reason.Message) -ForegroundColor Red
                }
            }
            else {

                Write-Host "$($j.Name) $($j.State) successfully"
            }
        }       
    }
}
...