Skip to content
This repository has been archived by the owner. It is now read-only.

Question: Expiration allmost never happens on it's own in the background #248

Closed
ChrisRichner opened this issue Nov 4, 2016 · 4 comments

Comments

Projects
None yet
2 participants
@ChrisRichner
Copy link

commented Nov 4, 2016

I'm currently implementing a class which should mimic session timeouts. Before writing this on my own I've thought taking the IMemoryCache implementation should do the trick as well.

I'm having a plain vanilla asp.net core web api project. I've added the nuget package to project.json and added the following code:

Startup.cs -> services.AddMemoryCache(c => c.CompactOnMemoryPressure = false);

Then I'm going to use the ctor injected IMemoryCache instance in my class by TryGetValue to get out an existing item or Set() to add a new one.

I use RegisterPostEvictionCallback to run some code when the item expires and add an expiration token to be able to have a Reset() method which expires all items at once -> Clear()

if (MemoryCache.TryGetValue<TokenSessionMapping>(key, out tsm))
            {
                return tsm;
            }

 MemoryCache.Set(key, tsm,
                        new MemoryCacheEntryOptions()
                            .SetSlidingExpiration(TimeSpan.FromSeconds(15))

                            .SetAbsoluteExpiration(TimeSpan.FromHours(1))

                            .RegisterPostEvictionCallback(PostEvictionCallback)

                            .AddExpirationToken(new CancellationChangeToken(CancellationTokenSource.Token))
                            );

The problem I'm having is that the items don't expire automatically. It needs another web api call that accesses the Set() method to trigger the evicted callback on the already expired items.

Why didn't the evicted callback fire when the item expired in first place? I can't afford to have another web api to trigger the session timeouts for the system.

What do I miss?
Thanks!

@Tratcher

This comment has been minimized.

Copy link
Member

commented Nov 4, 2016

This is by design, there's no timer thread that actively scans the cache for expired items. We didn't want a timer always running on an otherwise idle site. Any activity on the cache (Get, Set, Remove) can trigger a background scan for expired items. A timer on the CancellationTokenSource (CancelAfter) would also remove the entry and trigger a scan for expired items.

@ChrisRichner

This comment has been minimized.

Copy link
Author

commented Nov 4, 2016

Thank you for explaining why I'm facing this issue!

Can you elaborate a bit what you mean by

A timer on the CancellationTokenSource (CancelAfter) would also remove the entry and trigger a scan for expired items.

What alternatives do exists for my use case?

@Tratcher

This comment has been minimized.

Copy link
Member

commented Nov 4, 2016

Rather than using SetAbsoluteExpiration(TimeSpan.FromHours(1)) you could instead use CancellationTokenSource.CancelAfter(TimeSpan.FromHours(1)) for the token you're already registering. When this token fires it will remove the entry immediately and fire the eviction callbacks.

@ChrisRichner

This comment has been minimized.

Copy link
Author

commented Nov 6, 2016

I see, thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.