Преглед изворни кода

Fix deploy wipe/extract race that could break admin site deploys

Remove-Item can report success while NTFS is still asynchronously
finishing a large recursive delete, so Expand-Archive -Force could
see leftover entries, queue them for removal itself, and lose the
race against our own delete completing - failing with "Cannot find
path ... because it does not exist" on the next deploy.
master
Daniel Covington пре 7 часа
родитељ
комит
65447d765d
1 измењених фајлова са 25 додато и 10 уклоњено
  1. +25
    -10
      scripts/deploy-iis-remote-apply.ps1

+ 25
- 10
scripts/deploy-iis-remote-apply.ps1 Прегледај датотеку

@@ -53,23 +53,38 @@ function Wait-AppPoolFullyStopped {
# Wipes are attempted a few times with a short pause - file handles (IIS or AV scanning
# the just-stopped worker process's files) can take a moment to release even after the
# worker process itself is confirmed gone.
#
# Remove-Item returning without an error is not proof the directory is actually empty yet -
# NTFS can finish a large recursive delete asynchronously, so a Get-ChildItem right after can
# still show remnants. If Expand-Archive -Force then runs against those remnants, it queues
# them for removal itself and can lose the race against our own delete finishing, failing with
# "Cannot find path ... because it does not exist". So after Remove-Item reports success, poll
# until the directory is verifiably empty before trusting the wipe is done.
function Remove-DirectoryContentsWithRetry {
param([string]$Path, [int]$MaxAttempts = 5, [int]$DelayMs = 2000)
param([string]$DirPath, [int]$MaxAttempts = 5, [int]$DelayMs = 2000)

for($attempt = 1; $attempt -le $MaxAttempts; $attempt++){
$failure = $null
$problem = $null
try {
Remove-Item -Recurse -Force $Path -ErrorAction Stop
return
Remove-Item -Recurse -Force (Join-Path $DirPath '*') -ErrorAction Stop
} catch {
$failure = $_
if($attempt -lt $MaxAttempts){
Write-Host "Wipe attempt $attempt failed (files still locked?) - retrying in $($DelayMs)ms"
Start-Sleep -Milliseconds $DelayMs
$problem = "delete failed: $($_.Exception.Message)"
}

if(!$problem){
if(!(Get-ChildItem -Force -LiteralPath $DirPath -ErrorAction SilentlyContinue)){
return
}
$problem = 'residual files still present after delete (async NTFS delete still finishing?)'
}

if($attempt -lt $MaxAttempts){
Write-Host "Wipe attempt $attempt failed ($problem) - retrying in $($DelayMs)ms"
Start-Sleep -Milliseconds $DelayMs
} else {
throw "Wipe of $DirPath did not complete after $MaxAttempts attempts - $problem"
}
}
throw $failure
}

if(!(Get-Website -Name $SiteName -ErrorAction SilentlyContinue)){
@@ -106,7 +121,7 @@ if(![string]::IsNullOrWhiteSpace($AdminSiteName) -and (Get-Website -Name $AdminS

if(Test-Path $RemoteDir){
Write-Host "Wiping $RemoteDir"
Remove-DirectoryContentsWithRetry -Path (Join-Path $RemoteDir '*')
Remove-DirectoryContentsWithRetry -DirPath $RemoteDir
} else {
New-Item -ItemType Directory -Force -Path $RemoteDir | Out-Null
}


Loading…
Откажи
Сачувај

Powered by TurnKey Linux.