Last active
March 3, 2023 19:47
-
-
Save JKerens/dd1426be8b77a2b2a90e7cfb34a80e73 to your computer and use it in GitHub Desktop.
Azure PowerShell Caching Idea
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $Script:cache ??= [ordered]@{} | |
| <# | |
| .EXAMPLE | |
| Import-Module .\Az.Module.Cache.psm1 | |
| $servers = Get-CachedItem -ValueFactory { Get-AzResource -ResourceType "Microsoft.Sql/servers" } -Verbose | |
| #> | |
| function Get-CachedItem { | |
| param( | |
| [Parameter(Mandatory = $true)] | |
| [scriptblock]$ValueFactory, | |
| [Parameter(Mandatory = $false)] | |
| [int]$ExpiresInMinutes = 5 | |
| ) | |
| [TimeSpan]$ExpirationTime = [TimeSpan]::FromMinutes($ExpiresInMinutes) | |
| # Hash the command in a safe deterministic way | |
| $commandAst = [System.Management.Automation.Language.Parser]::ParseInput($ValueFactory.ToString(), [ref]$null, [ref]$null) | |
| $commandBase64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($commandAst.ToString())) | |
| # Tack on the subscription to avoid bugs when switching subscriptions | |
| $subscription = (Get-AzContext) ?? "NA" | |
| $Key = "$($subscription.Subscription.Id):$($commandBase64)" | |
| $cachedItem = Get-CachedItemFromCache $Key | |
| if ($cachedItem -and (Get-Date) -lt $cachedItem.Expires) { | |
| # Item exists in cache and hasn't expired, return the cached value | |
| Write-Verbose "Cache Hit Found" | |
| return $cachedItem.Value | |
| } | |
| Write-Verbose "Cache Miss, Adding Record" | |
| # Item doesn't exist in cache or has expired, generate a new value and cache it | |
| $value = Invoke-Command $ValueFactory | |
| $expires = (Get-Date).Add($ExpirationTime) | |
| Add-CachedItemToCache $Key $value $expires | |
| Remove-ExpiredCache | |
| return $value | |
| } | |
| function Get-CachedItemFromCache { | |
| param( | |
| [Parameter(Mandatory = $true)] | |
| [string]$Key | |
| ) | |
| return ($Script:cache.Contains($Key)) ` | |
| ? $Script:cache[$Key] | |
| : $null | |
| } | |
| function Add-CachedItemToCache { | |
| param( | |
| [Parameter(Mandatory = $true)] | |
| [string]$Key, | |
| [Parameter(Mandatory = $true)] | |
| $Value, | |
| [Parameter(Mandatory = $true)] | |
| [DateTime]$Expires | |
| ) | |
| $Script:cache[$Key] = [PSCustomObject]@{ | |
| Value = $Value | |
| Expires = $Expires | |
| } | |
| } | |
| # For debugging JIC | |
| function Get-Cache { | |
| return $Script:cache | |
| } | |
| function Clear-Cache { | |
| $Script:cache = [ordered]@{} | |
| } | |
| function Remove-ExpiredCache { | |
| # This is to prevent editing an enumeration while looping on it | |
| $keys = $Script:cache.GetEnumerator() | ForEach-Object { $_.Key } | |
| $keys | ForEach-Object { | |
| if ((Get-Date) -ge $Script:cache[$_].Expires) { | |
| Write-Verbose "Removing Stale Cache Entry $_" | |
| $Script:cache.Remove($_) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment