Public/Task/Wait-VergeTask.ps1
|
function Wait-VergeTask { <# .SYNOPSIS Waits for a VergeOS task to complete. .DESCRIPTION Wait-VergeTask polls the status of a task until it completes (becomes idle) or the specified timeout is reached. This is useful for synchronous operations where you need to wait for a background task to finish. .PARAMETER Task A task object from Get-VergeTask. Accepts pipeline input. .PARAMETER Key The unique key (ID) of the task to wait for. .PARAMETER Name The name of the task to wait for. .PARAMETER TimeoutSeconds Maximum time to wait in seconds. Default is 300 (5 minutes). Use 0 for infinite wait. .PARAMETER PollingIntervalSeconds How often to check task status in seconds. Default is 2. .PARAMETER PassThru Return the task object when completed. By default, returns nothing on success. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE Wait-VergeTask -Name "Backup VM" Waits for the task named "Backup VM" to complete. .EXAMPLE Get-VergeTask -Running | Wait-VergeTask Waits for all running tasks to complete. .EXAMPLE Wait-VergeTask -Key 5 -TimeoutSeconds 600 -PassThru Waits up to 10 minutes for task with key 5 and returns the task when complete. .EXAMPLE Get-VergeTask -Name "Clone*" | Wait-VergeTask -PollingIntervalSeconds 5 Waits for all clone tasks, checking every 5 seconds. .OUTPUTS None by default. Verge.Task when -PassThru is specified. .NOTES The cmdlet shows progress while waiting. Use Get-VergeTask to check task status manually. #> [CmdletBinding(DefaultParameterSetName = 'ByTask')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByTask')] [PSTypeName('Verge.Task')] [PSCustomObject]$Task, [Parameter(Mandatory, ParameterSetName = 'ByKey')] [int]$Key, [Parameter(Mandatory, ParameterSetName = 'ByName')] [string]$Name, [Parameter()] [ValidateRange(0, [int]::MaxValue)] [int]$TimeoutSeconds = 300, [Parameter()] [ValidateRange(1, 60)] [int]$PollingIntervalSeconds = 2, [Parameter()] [switch]$PassThru, [Parameter()] [object]$Server ) begin { # Resolve connection if (-not $Server) { $Server = $script:DefaultConnection } if (-not $Server) { throw [System.InvalidOperationException]::new( 'Not connected to VergeOS. Use Connect-VergeOS to establish a connection.' ) } } process { # Get the task to wait for based on parameter set $targetTask = switch ($PSCmdlet.ParameterSetName) { 'ByTask' { $Task } 'ByKey' { Get-VergeTask -Key $Key -Server $Server } 'ByName' { Get-VergeTask -Name $Name -Server $Server | Select-Object -First 1 } } if (-not $targetTask) { Write-Error -Message "Task not found" -ErrorId 'TaskNotFound' return } # If task is already idle, return immediately if (-not $targetTask.IsRunning) { Write-Verbose "Task '$($targetTask.Name)' is already idle" if ($PassThru) { Write-Output $targetTask } return } $taskKey = $targetTask.Key $taskName = $targetTask.Name $startTime = Get-Date $progressId = Get-Random Write-Verbose "Waiting for task '$taskName' (Key: $taskKey) to complete..." try { while ($true) { # Check timeout $elapsed = (Get-Date) - $startTime if ($TimeoutSeconds -gt 0 -and $elapsed.TotalSeconds -ge $TimeoutSeconds) { Write-Progress -Id $progressId -Activity "Waiting for task" -Completed throw [System.TimeoutException]::new( "Timeout waiting for task '$taskName' after $TimeoutSeconds seconds" ) } # Get current task status $currentTask = Get-VergeTask -Key $taskKey -Server $Server if (-not $currentTask) { Write-Progress -Id $progressId -Activity "Waiting for task" -Completed throw [System.InvalidOperationException]::new( "Task '$taskName' no longer exists" ) } # Check if completed if (-not $currentTask.IsRunning) { Write-Progress -Id $progressId -Activity "Waiting for task" -Completed Write-Verbose "Task '$taskName' completed after $([int]$elapsed.TotalSeconds) seconds" if ($PassThru) { Write-Output $currentTask } return } # Update progress $statusText = "Task '$taskName' - Status: $($currentTask.Status)" if ($TimeoutSeconds -gt 0) { $percentComplete = [Math]::Min(100, [int](($elapsed.TotalSeconds / $TimeoutSeconds) * 100)) $remainingSeconds = $TimeoutSeconds - [int]$elapsed.TotalSeconds Write-Progress -Id $progressId -Activity "Waiting for task to complete" ` -Status $statusText ` -PercentComplete $percentComplete ` -SecondsRemaining $remainingSeconds } else { Write-Progress -Id $progressId -Activity "Waiting for task to complete" ` -Status $statusText ` -PercentComplete -1 } # Wait before next poll Start-Sleep -Seconds $PollingIntervalSeconds } } finally { Write-Progress -Id $progressId -Activity "Waiting for task" -Completed -ErrorAction SilentlyContinue } } } |