Skip to content

Commit ab15097

Browse files
committed
Update Start-DurableCleanup.ps1
1 parent 0f5dd3c commit ab15097

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-DurableCleanup.ps1

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,80 @@ function Start-DurableCleanup {
1717
param(
1818
[int]$MaxDuration = 86400
1919
)
20-
Write-Information "This cleanup is no longer required."
20+
21+
$WarningPreference = 'SilentlyContinue'
22+
$TargetTime = (Get-Date).ToUniversalTime().AddSeconds(-$MaxDuration)
23+
$Context = New-AzDataTableContext -ConnectionString $env:AzureWebJobsStorage
24+
$InstancesTables = Get-AzDataTable -Context $Context | Where-Object { $_ -match 'Instances' }
25+
26+
$CleanupCount = 0
27+
$QueueCount = 0
28+
29+
$FunctionsWithLongRunningOrchestrators = [System.Collections.Generic.List[object]]::new()
30+
$NonDeterministicOrchestrators = [System.Collections.Generic.List[object]]::new()
31+
32+
foreach ($Table in $InstancesTables) {
33+
$Table = Get-CippTable -TableName $Table
34+
$FunctionName = $Table.TableName -replace 'Instances', ''
35+
$Orchestrators = Get-CIPPAzDataTableEntity @Table -Filter "RuntimeStatus eq 'Running'" | Select-Object * -ExcludeProperty Input
36+
$Queues = Get-AzStorageQueue -Context $StorageContext -Name ('{0}*' -f $FunctionName) | Select-Object -Property Name, ApproximateMessageCount, QueueClient
37+
$LongRunningOrchestrators = $Orchestrators | Where-Object { $_.CreatedTime.DateTime -lt $TargetTime }
38+
39+
if ($LongRunningOrchestrators.Count -gt 0) {
40+
$FunctionsWithLongRunningOrchestrators.Add(@{'FunctionName' = $FunctionName })
41+
foreach ($Orchestrator in $LongRunningOrchestrators) {
42+
$CreatedTime = [DateTime]::SpecifyKind($Orchestrator.CreatedTime.DateTime, [DateTimeKind]::Utc)
43+
$TimeSpan = New-TimeSpan -Start $CreatedTime -End (Get-Date).ToUniversalTime()
44+
$RunningDuration = [math]::Round($TimeSpan.TotalMinutes, 2)
45+
Write-Information "Orchestrator: $($Orchestrator.PartitionKey), created: $CreatedTime, running for: $RunningDuration minutes"
46+
if ($PSCmdlet.ShouldProcess($_.PartitionKey, 'Terminate Orchestrator')) {
47+
$Orchestrator = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq '$($Orchestrator.PartitionKey)'"
48+
$Orchestrator.RuntimeStatus = 'Failed'
49+
if ($Orchestrator.PSObject.Properties.Name -contains 'CustomStatus') {
50+
$Orchestrator.CustomStatus = "Terminated by Durable Cleanup - Exceeded max duration of $MaxDuration seconds"
51+
} else {
52+
$Orchestrator | Add-Member -MemberType NoteProperty -Name CustomStatus -Value "Terminated by Durable Cleanup - Exceeded max duration of $MaxDuration seconds"
53+
}
54+
Update-AzDataTableEntity @Table -Entity $Orchestrator
55+
$CleanupCount++
56+
}
57+
}
58+
}
59+
60+
$NonDeterministicOrchestrators = $Orchestrators | Where-Object { $_.Output -match 'Non-Deterministic workflow detected' }
61+
if ($NonDeterministicOrchestrators.Count -gt 0) {
62+
$NonDeterministicOrchestrators.Add(@{'FunctionName' = $FunctionName })
63+
foreach ($Orchestrator in $NonDeterministicOrchestrators) {
64+
Write-Information "Orchestrator: $($Orchestrator.PartitionKey) is Non-Deterministic"
65+
if ($PSCmdlet.ShouldProcess($_.PartitionKey, 'Terminate Orchestrator')) {
66+
$Orchestrator = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq '$($Orchestrator.PartitionKey)'"
67+
$Orchestrator.RuntimeStatus = 'Failed'
68+
if ($Orchestrator.PSObject.Properties.Name -contains 'CustomStatus') {
69+
$Orchestrator.CustomStatus = 'Terminated by Durable Cleanup - Non-Deterministic workflow detected'
70+
} else {
71+
$Orchestrator | Add-Member -MemberType NoteProperty -Name CustomStatus -Value 'Terminated by Durable Cleanup - Non-Deterministic workflow detected'
72+
}
73+
Update-AzDataTableEntity @Table -Entity $Orchestrator
74+
$CleanupCount++
75+
}
76+
}
77+
}
78+
79+
if (($LongRunningOrchestrators.Count -gt 0 -or $NonDeterministicOrchestrators.Count -gt 0) -and $Queues.ApproximateMessageCount -gt 0) {
80+
$RunningQueues = $Queues | Where-Object { $_.ApproximateMessageCount -gt 0 }
81+
foreach ($Queue in $RunningQueues) {
82+
Write-Information "- Removing queue: $($Queue.Name), message count: $($Queue.ApproximateMessageCount)"
83+
if ($PSCmdlet.ShouldProcess($Queue.Name, 'Clear Queue')) {
84+
$Queue.QueueClient.ClearMessagesAsync() | Out-Null
85+
}
86+
$QueueCount++
87+
}
88+
}
89+
}
90+
91+
if ($CleanupCount -gt 0 -or $QueueCount -gt 0) {
92+
Write-LogMessage -api 'Durable Cleanup' -message "$CleanupCount orchestrators were terminated. $QueueCount queues were cleared." -sev 'Info' -LogData $FunctionsWithLongRunningOrchestrators
93+
}
94+
95+
Write-Information "Durable cleanup complete. $CleanupCount orchestrators were terminated. $QueueCount queues were cleared."
2196
}

0 commit comments

Comments
 (0)