I'm investigating how to build cache expiry handlers with PowerShell. The below script indicates that goal and the expected output.
$RemovedAction = {
param([System.Runtime.Caching.CacheEntryRemovedArguments]$Arguments)
$Key = $Arguments.CacheItem.Key
$Item = $Arguments.CacheItem
$RemovedObject = $Arguments.CacheItem.Value
$RemovedReason = $Arguments.RemovedReason
Write-Host -ForegroundColor Yellow "About to be removed from cache: $Key :
$RemovedReason"
}
# Build a cache, create a policy that references the callback and add items to the cache.
$MC = New-Object System.Runtime.Caching.MemoryCache('Main')
$Policy = New-Object System.Runtime.Caching.CacheItemPolicy
$Policy.AbsoluteExpiration = (Get-DAte).ToUniversalTime().AddSeconds(4) #N.B. It's always in UTC.
$Policy.RemovedCallback = $RemovedAction
$A = [PSCustomObject]@{ Name = 'Albert'; Age = 21 }
$B = [PSCustomObject]@{ Name = 'Bob'; Age = 21 }
[void]$MC.Set('A',$A, $Policy)
[void]$MC.Set('B',$B, $Policy)
Start-Sleep -Seconds 1
Write-Host -ForegroundColor Green "Expect Bob to be expired immediately..."
[Void]$MC.Remove('B') # Expect to see Bob be expired.
Write-Host -ForegroundColor Green "Expect Albert to be expired due to the timeout, clearly it's in the cache at the start of the sleep."
$MC
Start-Sleep -Seconds 6
Write-Host -ForegroundColor Green "See, Albert has gone, as it's not in the cache, but it does not look as thouh the delegate was triggered."
$MC
The result of this is that the explicit example of removing "Albert" works as expected, with the handler being called with the correct argument, however the implicit example with the absolute expiration time does not seem to work as expected.
In the latter case it seems that the item does expire from the cache (as we can see from the fact it doesn't get printed out) however it does not appear that the callback was indeed called.
I suspect this may be a threading issue, but it is not clear to me what is going on here.
This is a stepping stone to implementing a custom change monitor callback.