2

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.

user1383092
  • 507
  • 1
  • 7
  • 17

1 Answers1

2

This answer is a year late, but for anyone who finds there way here - expiration doesn't trigger the callback. The first time you call for the data AFTER it expires is what triggers the callback. See MemoryCache AbsoluteExpiration acting strange

Start-Sleep -Seconds 6
$MC.Get('A') | out-null
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."
  • Could you elaborate more on your answer and post some code for the illustration purpose? – Artem Oct 03 '18 at 15:24
  • @Artem - I just edited my answer to include the change I made in the original code that gets the expiration callback to fire. – user3085241 Oct 04 '18 at 13:13