improve caching for static rendering
This commit is contained in:
parent
553bbda769
commit
aac4d3eefb
79
Oqtane.Server/Extensions/CacheExtensions.cs
Normal file
79
Oqtane.Server/Extensions/CacheExtensions.cs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Oqtane.Extensions
|
||||||
|
{
|
||||||
|
public static class CacheExtensions
|
||||||
|
{
|
||||||
|
private static string _cachekeys = "cachekeys";
|
||||||
|
|
||||||
|
public static TItem GetOrCreate<TItem>(this IMemoryCache cache, string key, Func<ICacheEntry, TItem> factory, bool track)
|
||||||
|
{
|
||||||
|
if (!cache.TryGetValue(key, out object result))
|
||||||
|
{
|
||||||
|
using ICacheEntry entry = cache.CreateEntry(key);
|
||||||
|
result = factory(entry);
|
||||||
|
entry.Value = result;
|
||||||
|
|
||||||
|
if (track)
|
||||||
|
{
|
||||||
|
// track the cache key
|
||||||
|
List<string> cachekeys;
|
||||||
|
if (!cache.TryGetValue(_cachekeys, out cachekeys))
|
||||||
|
{
|
||||||
|
cachekeys = new List<string>();
|
||||||
|
}
|
||||||
|
if (!cachekeys.Contains(key))
|
||||||
|
{
|
||||||
|
cachekeys.Add(key);
|
||||||
|
cache.Set(_cachekeys, cachekeys, new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TItem)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Remove(this IMemoryCache cache, string key, bool track)
|
||||||
|
{
|
||||||
|
List<string> cachekeys;
|
||||||
|
|
||||||
|
if (track && key.EndsWith("*"))
|
||||||
|
{
|
||||||
|
// wildcard cache key removal
|
||||||
|
var prefix = key.Substring(0, key.Length - 1);
|
||||||
|
if (cache.TryGetValue(_cachekeys, out cachekeys) && cachekeys.Any())
|
||||||
|
{
|
||||||
|
for (var i = cachekeys.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (cachekeys[i].StartsWith(prefix))
|
||||||
|
{
|
||||||
|
cache.Remove(cachekeys[i]);
|
||||||
|
cachekeys.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cache.Set(_cachekeys, cachekeys, new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cache.Remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reconcile all tracked cache keys
|
||||||
|
if (track && cache.TryGetValue(_cachekeys, out cachekeys) && cachekeys.Any())
|
||||||
|
{
|
||||||
|
for (var i = cachekeys.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (!cache.TryGetValue(cachekeys[i], out _))
|
||||||
|
{
|
||||||
|
cachekeys.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cache.Set(_cachekeys, cachekeys, new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Oqtane.Extensions;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ namespace Oqtane.Infrastructure.EventSubscribers
|
||||||
// when site entities change (ie. site, pages, modules, etc...) a site refresh event is raised and the site cache item needs to be refreshed
|
// when site entities change (ie. site, pages, modules, etc...) a site refresh event is raised and the site cache item needs to be refreshed
|
||||||
if (syncEvent.EntityName == EntityNames.Site && syncEvent.Action == SyncEventActions.Refresh)
|
if (syncEvent.EntityName == EntityNames.Site && syncEvent.Action == SyncEventActions.Refresh)
|
||||||
{
|
{
|
||||||
_cache.Remove($"site:{syncEvent.TenantId}:{syncEvent.EntityId}");
|
_cache.Remove($"site:{syncEvent.TenantId}:{syncEvent.EntityId}*", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// when a site entity is updated the hosting model may have changed, so the client assemblies cache items need to be refreshed
|
// when a site entity is updated the hosting model may have changed, so the client assemblies cache items need to be refreshed
|
||||||
|
|
|
@ -69,11 +69,15 @@ namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||||
return GetSite(siteId);
|
return GetSite(siteId);
|
||||||
});
|
}, true);
|
||||||
}
|
}
|
||||||
else
|
else // authenticated - cached per user
|
||||||
{
|
{
|
||||||
site = GetSite(siteId);
|
site = _cache.GetOrCreate($"site:{_accessor.HttpContext.GetAlias().SiteKey}:{_accessor.HttpContext.User.UserId}", entry =>
|
||||||
|
{
|
||||||
|
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||||
|
return GetSite(siteId);
|
||||||
|
}, true);
|
||||||
}
|
}
|
||||||
return await Task.Run(() => site);
|
return await Task.Run(() => site);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user