Skip to content

Commit ed0d2ec

Browse files
committed
durable cleanup
1 parent 6fbc4c2 commit ed0d2ec

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

CIPPTimers.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
[
2+
{
3+
"Command": "Start-DurableCleanup",
4+
"Description": "Timer function to cleanup durable functions",
5+
"Cron": "0 */15 * * * *",
6+
"Priority": 0,
7+
"RunOnProcessor": true,
8+
"IsSystem": true
9+
},
210
{
311
"Command": "Start-UserTasksOrchestrator",
412
"Description": "Orchestrator to process user scheduled tasks",
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
function Start-DurableCleanup {
2+
<#
3+
.SYNOPSIS
4+
Start the durable cleanup process.
5+
6+
.DESCRIPTION
7+
Look for orchestrators running for more than the specified time and terminate them. Also, clear any queues that have items for that function app.
8+
9+
.PARAMETER MaxDuration
10+
The maximum duration an orchestrator can run before being terminated.
11+
12+
.FUNCTIONALITY
13+
Internal
14+
#>
15+
16+
[CmdletBinding(SupportsShouldProcess = $true)]
17+
param(
18+
[int]$MaxDuration = 3600
19+
)
20+
$WarningPreference = 'SilentlyContinue'
21+
$StorageContext = New-AzStorageContext -ConnectionString $env:AzureWebJobsStorage
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+
foreach ($Table in $InstancesTables) {
29+
$Table = Get-CippTable -TableName $Table
30+
$ClearQueues = $false
31+
$FunctionName = $Table.TableName -replace 'Instances', ''
32+
$Orchestrators = Get-CIPPAzDataTableEntity @Table -Filter "RuntimeStatus eq 'Running'" | Select-Object * -ExcludeProperty Input
33+
$Orchestrators | Where-Object { $_.CreatedTime.DateTime -lt $TargetTime } | ForEach-Object {
34+
$CreatedTime = [DateTime]::SpecifyKind($_.CreatedTime.DateTime, [DateTimeKind]::Utc)
35+
$TimeSpan = New-TimeSpan -Start $CreatedTime -End (Get-Date).ToUniversalTime()
36+
$RunningDuration = [math]::Round($TimeSpan.TotalMinutes, 2)
37+
Write-Information "Orchestrator: $($_.PartitionKey), created: $CreatedTime, running for: $RunningDuration minutes"
38+
$ClearQueues = $true
39+
$_.RuntimeStatus = 'Failed'
40+
if ($PSCmdlet.ShouldProcess($_.PartitionKey, 'Terminate Orchestrator')) {
41+
$Orchestrator = Get-CIPPAzDataTableEntity @Table -PartitionKey $_.PartitionKey -RowKey $_.RowKey
42+
$Orchestrator.RuntimeStatus = 'Failed'
43+
Update-AzDataTableEntity @Table -Entity $Orchestrator
44+
$CleanupCount++
45+
}
46+
}
47+
48+
if ($ClearQueues) {
49+
$Queues = Get-AzStorageQueue -Context $StorageContext -Name ('{0}*' -f $FunctionName) | Select-Object -Property Name, ApproximateMessageCount, QueueClient
50+
$RunningQueues = $Queues | Where-Object { $_.ApproximateMessageCount -gt 0 }
51+
foreach ($Queue in $RunningQueues) {
52+
Write-Information "- Removing queue: $($Queue.Name), message count: $($Queue.ApproximateMessageCount)"
53+
if ($PSCmdlet.ShouldProcess($Queue.Name, 'Clear Queue')) {
54+
$Queue.QueueClient.ClearMessagesAsync() | Out-Null
55+
}
56+
$QueueCount++
57+
}
58+
}
59+
}
60+
Write-Information "Cleanup complete. $CleanupCount orchestrators were terminated. $QueueCount queues were cleared."
61+
}

0 commit comments

Comments
 (0)