Fix bidirectional RF-001A coordination

This commit is contained in:
LittleSam129
2026-09-21 18:05:28 +03:00
parent bc55d0516d
commit a516b99015
17 changed files with 1745 additions and 244 deletions

View File

@@ -0,0 +1,104 @@
param(
[Parameter(Mandatory = $true)][string]$Executable,
[Parameter(Mandatory = $true)][string]$ArgumentsJsonPath,
[Parameter(Mandatory = $true)][string]$CapturePath,
[Parameter(Mandatory = $true)][string]$StdoutPath,
[Parameter(Mandatory = $true)][string]$StderrPath,
[Parameter(Mandatory = $true)][string]$StartedStatusPath,
[Parameter(Mandatory = $true)][string]$ResultStatusPath
)
$ErrorActionPreference = 'Stop'
function Write-JsonAtomically {
param(
[Parameter(Mandatory = $true)][object]$Value,
[Parameter(Mandatory = $true)][string]$Path
)
$temporaryPath = "$Path.tmp"
$json = $Value | ConvertTo-Json -Depth 8
$encoding = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($temporaryPath, $json + [Environment]::NewLine, $encoding)
Move-Item -LiteralPath $temporaryPath -Destination $Path -Force
}
$decodedArguments = Get-Content -Raw -LiteralPath $ArgumentsJsonPath |
ConvertFrom-Json
if ($decodedArguments -isnot [System.Array]) {
throw 'ArgumentsJsonPath must contain a JSON array.'
}
$childArguments = @(
foreach ($argument in $decodedArguments) {
[string]$argument
}
)
$startedAt = [DateTimeOffset]::UtcNow
$finishedAt = $null
$childProcess = $null
$exitCode = $null
$runnerError = $null
$captureSize = 0
$sha256 = $null
try {
$startParameters = @{
FilePath = $Executable
ArgumentList = $childArguments
RedirectStandardOutput = $StdoutPath
RedirectStandardError = $StderrPath
PassThru = $true
WindowStyle = 'Hidden'
}
$childProcess = Start-Process @startParameters
# PowerShell 5 can lose ExitCode for redirected processes unless the
# underlying process handle is opened before WaitForExit().
$null = $childProcess.Handle
Write-JsonAtomically -Path $StartedStatusPath -Value ([ordered]@{
state = 'RUNNING'
pid = $childProcess.Id
started_at = $startedAt.ToString('o')
capture_path = $CapturePath
})
$childProcess.WaitForExit()
$childProcess.Refresh()
$exitCode = [int]$childProcess.ExitCode
} catch {
$runnerError = $_.Exception.ToString()
} finally {
$finishedAt = [DateTimeOffset]::UtcNow
if (Test-Path -LiteralPath $CapturePath) {
try {
$captureSize = [int64](Get-Item -LiteralPath $CapturePath).Length
$sha256 = (
Get-FileHash -LiteralPath $CapturePath -Algorithm SHA256
).Hash.ToLowerInvariant()
} catch {
$additionalError = $_.Exception.ToString()
if ([string]::IsNullOrWhiteSpace($runnerError)) {
$runnerError = $additionalError
} else {
$runnerError = $runnerError + [Environment]::NewLine + $additionalError
}
}
}
Write-JsonAtomically -Path $ResultStatusPath -Value ([ordered]@{
pid = if ($null -ne $childProcess) { $childProcess.Id } else { $null }
started_at = $startedAt.ToString('o')
finished_at = $finishedAt.ToString('o')
duration = ($finishedAt - $startedAt).TotalSeconds
exit_code = $exitCode
capture_path = $CapturePath
capture_size = $captureSize
sha256 = $sha256
runner_error = $runnerError
})
}
if ($null -eq $exitCode) {
exit 255
}
exit $exitCode