Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In-memory cache GetOrCreate with MemoryCacheEntryOptions

In current implementation IMemoryCache interface has the following methods:

bool TryGetValue(object key, out object value);
ICacheEntry CreateEntry(object key);
void Remove(object key);

We have the possibility to query the cache for an entry in the following way:

//first way
if (string.IsNullOrEmpty
(cache.Get<string>("timestamp")))
{
  cache.Set<string>("timestamp", DateTime.Now.ToString());
}

//second way
if (!cache.TryGetValue<string>
("timestamp", out string timestamp))
{
    //
    cache.Set<string>("timestamp", DateTime.Now.ToString());
}

But there is another method that should do what a cache should do (GetOrCreate) with a factory parameter:

public static TItem GetOrCreate<TItem>(this IMemoryCache cache, object key, Func<ICacheEntry, TItem> factory)
{
   object obj;
   if (!cache.TryGetValue(key, out obj))
   {
     ICacheEntry entry = cache.CreateEntry(key);
     obj = (object) factory(entry);
     entry.SetValue(obj);
     entry.Dispose();
   }
   return (TItem) obj;
}

As you can see above, the Set method accepts MemoryCacheEntryOptions or any absoluteExpirationRelativeToNow, absoluteExpiration, etc dates (https://github.com/aspnet/Caching/blob/12f998d69703fb0f62b5cb1c123b76d63e0d04f0/src/Microsoft.Extensions.Caching.Abstractions/MemoryCacheExtensions.cs), but GetOrCreate method doesn't support that type of 'per-entry-expiration-date' for when we create a new entry.

I'm trying to figure out if i'm missing something or if i should do a PR to add those methods.

Annex:

public static ICacheEntry SetValue(this ICacheEntry entry, object value)
{
   entry.Value = value;
   return entry;
 }

Opened an issue here: https://github.com/aspnet/Caching/issues/392 in order to get some more feedback.

like image 869
Razvan Dumitru Avatar asked May 09 '18 07:05

Razvan Dumitru


1 Answers

I'm not sure if I have understood correctly, but you can set all the 'per-entry-expiration-date' options on the entry you are receiving as the parameter to your factory:

string timestamp = cache.GetOrCreate("timestamp", entry =>
{
    entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(5);

    return DateTime.Now.ToString();
});

 

string timestamp = cache.GetOrCreate("timestamp", entry =>
{
    entry.SlidingExpiration = TimeSpan.FromSeconds(5);

    return DateTime.Now.ToString();
});

All the MemoryCacheEntryOptions are available on ICacheEntry.

like image 137
tpeczek Avatar answered Sep 29 '22 09:09

tpeczek