Last active
March 31, 2025 03:34
-
-
Save jermdavis/fc4c8004ba1bd21540c8d2561ae4b279 to your computer and use it in GitHub Desktop.
A fix to make https://briancaos.wordpress.com/2017/05/01/sitecore-caching-clear-caches-individually/ work on Sitecore 10, plus a quick hack to view the contents of each cache (for data that can be easily displayed)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ page language="c#" enableeventvalidation="false" autoeventwireup="true" enableviewstate="false" %> | |
<%@ import namespace="System.Security.Permissions" %> | |
<%@ import namespace="System.Collections.Generic" %> | |
<%@ import namespace="System.Threading" %> | |
<%@ import namespace="System.Security.Principal" %> | |
<%@ import namespace="Newtonsoft.Json" %> | |
<%@ import namespace="Sitecore.Data.Items" %> | |
<script runat="server"> | |
void Page_Load(object sender, System.EventArgs e) | |
{ | |
Response.Buffer = false; | |
Response.BufferOutput = false; | |
DataBind(); | |
} | |
IEnumerable<Sitecore.Caching.ICacheInfo> Caches | |
{ | |
get | |
{ | |
string name = Request.QueryString["name"]; | |
if(!string.IsNullOrWhiteSpace(name)) | |
{ | |
return Sitecore.Caching.CacheManager.GetAllCaches().Where(c => c.Name.StartsWith(name)).OrderBy(c => c.Name); | |
} | |
return Sitecore.Caching.CacheManager.GetAllCaches().OrderBy(c => c.Name); | |
} | |
} | |
double PercentageUsed(Sitecore.Caching.ICacheInfo cache) | |
{ | |
if (cache.MaxSize == 0) | |
return 0; | |
return Math.Round(((double)cache.Size/(double)cache.MaxSize*100), 0); | |
} | |
string PercentageColor(double percentage) | |
{ | |
if (percentage >= 0 && percentage <= 50) | |
return "green"; | |
if (percentage >= 50 && percentage <= 75) | |
return "orange"; | |
return "red"; | |
} | |
private void repCaches_Command(object source, RepeaterCommandEventArgs e) | |
{ | |
switch (e.CommandName) | |
{ | |
case "ClearCache": | |
string cacheName = e.CommandArgument as string; | |
var cache = Sitecore.Caching.CacheManager.GetAllCaches().Where(c => c.Name == cacheName).FirstOrDefault(); | |
if (cache == null) | |
{ | |
Response.Write("<div>NULL</div>"); | |
} | |
else | |
{ | |
cache.Clear(); | |
repCaches.DataBind(); | |
} | |
break; | |
case "ViewCache": | |
string cn = e.CommandArgument as string; | |
var cc = Sitecore.Caching.CacheManager.GetAllCaches().Where(c => c.Name == cn).FirstOrDefault(); | |
if(cc == null) | |
{ | |
Response.Write("<div>NULL</div>"); | |
return; | |
} | |
if(cc is Sitecore.Caching.Generics.ICache<string>) | |
{ | |
Enumerate<string>(cc); | |
} | |
else if(cc is Sitecore.Caching.Generics.ICache<Sitecore.Data.ID>) | |
{ | |
Enumerate<Sitecore.Data.ID>(cc); | |
} | |
else if(cc is Sitecore.Caching.Generics.ICache<Sitecore.Caching.ItemPathCacheKey>) | |
{ | |
Enumerate<Sitecore.Caching.ItemPathCacheKey>(cc); | |
} | |
else | |
{ | |
Response.Write("<div>Type: " + cc.GetType() + "</div>"); | |
} | |
Response.End(); | |
break; | |
} | |
} | |
void Enumerate<T>(Sitecore.Caching.ICacheInfo cache) | |
{ | |
var cc = cache as Sitecore.Caching.Generics.ICache<T>; | |
Response.Write("<h2>Cache type: " + string.Join(", ",cc.GetType().GetInterfaces().Select(t=>GetTypeName(t))) + "</h2>"); | |
var keys = cc.GetCacheKeys(); | |
if(keys.Length == 0) | |
{ | |
Response.Write("<div>Empty</div>"); | |
return; | |
} | |
Response.Write("<table border=2 cellpadding=3>"); | |
foreach(var key in keys) | |
{ | |
Response.Write("<tr>"); | |
var value = cc[key]; | |
if(value == null) | |
{ | |
Response.Write("<td>" + key + "</td><td>null</td>"); | |
} | |
else if(value is Sitecore.Data.Items.Item) | |
{ | |
var i = (Item)value; | |
Response.Write("<td>" + key + "</td><td>Item:" + i.Paths.Path + "</td>"); | |
} | |
else if(value is string) | |
{ | |
Response.Write("<td>" + key + "</td><td>" + value + "</td>"); | |
} | |
else if(value is System.Runtime.Serialization.ISerializable) | |
{ | |
Response.Write("<td>" + key + "</td><td>" + JsonConvert.SerializeObject(value) + "</td>"); | |
} | |
else | |
{ | |
Response.Write("<td>" + key + "</td><td>" + value + "</td>"); | |
} | |
Response.Write("</tr>"); | |
} | |
Response.Write("</table>"); | |
} | |
long TotalMaxSize() | |
{ | |
long ac = 0; | |
foreach (var cache in Caches) | |
ac = ac + cache.MaxSize; | |
return ac; | |
} | |
long TotalSize() | |
{ | |
long ac = 0; | |
foreach (var cache in Caches) | |
ac += cache.Size; | |
return ac; | |
} | |
double TotalPercentageUsed() | |
{ | |
if (TotalMaxSize() == 0) | |
return 0; | |
return Math.Round(((double)TotalSize()/(double)TotalMaxSize()*100), 1); | |
} | |
public static string GetTypeName(Type type) | |
{ | |
if (!type.IsGenericType) | |
return GetNestedTypeName(type); | |
StringBuilder stringBuilder = new StringBuilder(); | |
_buildClassNameRecursiv(type, stringBuilder); | |
return stringBuilder.ToString(); | |
} | |
private static void _buildClassNameRecursiv(Type type, StringBuilder classNameBuilder, int genericParameterIndex = 0) | |
{ | |
if (type.IsGenericParameter) | |
classNameBuilder.AppendFormat("T{0}", genericParameterIndex + 1); | |
else if (type.IsGenericType) | |
{ | |
classNameBuilder.Append(GetNestedTypeName(type) + "["); | |
int subIndex = 0; | |
foreach (Type genericTypeArgument in type.GetGenericArguments()) | |
{ | |
if (subIndex > 0) | |
classNameBuilder.Append(":"); | |
_buildClassNameRecursiv(genericTypeArgument, classNameBuilder, subIndex++); | |
} | |
classNameBuilder.Append("]"); | |
} | |
else | |
classNameBuilder.Append(GetNestedTypeName(type)); | |
} | |
public static string GetNestedTypeName(Type type) | |
{ | |
if (!type.IsNested) | |
return type.Name; | |
StringBuilder nestedName = new StringBuilder(); | |
while(type != null) | |
{ | |
if(nestedName.Length>0) | |
nestedName.Insert(0,'.'); | |
nestedName.Insert(0, _getTypeName(type)); | |
type = type.DeclaringType; | |
} | |
return nestedName.ToString(); | |
} | |
private static string _getTypeName(Type type) | |
{ | |
return type.IsGenericType ? type.Name.Split('`')[0]: type.Name; | |
} | |
</script> | |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > | |
<html> | |
<head> | |
<title>Cache Plus</title> | |
<style type="text/css"> | |
body { | |
font: normal 12pt arial, verdana; | |
padding: 20px; | |
} | |
.box { | |
padding: 20px; | |
margin: 20px; | |
border: solid 1px black; | |
background-color: #efefef; | |
} | |
input { | |
height: 30px; | |
width: 100px; | |
} | |
td { | |
border-bottom: solid 1px #aaa; | |
padding-right: 20px; | |
padding-left: 5px; | |
padding-top: 5px; | |
padding-bottom: 5px; | |
} | |
table { | |
width: 100%; | |
} | |
thead td { | |
font-weight: bold; | |
border-bottom: solid 1px #aaa; | |
padding-right: 20px; | |
} | |
</style> | |
</head> | |
<body style="font-size: 14px"> | |
<form runat="server"> | |
<div style="padding: 20px; background-color: #eaeaea; border-bottom: solid 1px #777777; font-size: 16px"> | |
<%# Sitecore.MainUtil.FormatSize(TotalSize(),false) %> of <%# Sitecore.MainUtil.FormatSize(TotalMaxSize(),false) %> used <strong>(<%# TotalPercentageUsed() %>%)</strong> | |
</div> | |
<asp:Repeater ID="repCaches" runat="server" EnableViewState="false" OnItemCommand="repCaches_Command" DataSource="<%# Caches %>"> | |
<headertemplate> | |
<table> | |
<thead> | |
<tr> | |
<td>Name</td> | |
<td></td> | |
<td>Size</td> | |
<td>MaxSize</td> | |
<td>% Used</td> | |
</tr> | |
</thead> | |
</headertemplate> | |
<footertemplate> | |
</table> | |
</footertemplate> | |
<itemtemplate> | |
<tr> | |
<td style="width: 250px"> | |
<a href="?name=<%# (Container.DataItem as Sitecore.Caching.ICacheInfo).Name %>"> | |
<%# (Container.DataItem as Sitecore.Caching.ICacheInfo).Name %> | |
</a> | |
</td> | |
<td style="width: 100px"> | |
<asp:Button ID="btnClearCache" runat="server" CommandArgument="<%# (Container.DataItem as Sitecore.Caching.ICacheInfo).Name %>" CommandName="ClearCache" text="Clear Cache" /> | |
<asp:Button ID="btnViewCache" runat="server" CommandArgument="<%# (Container.DataItem as Sitecore.Caching.ICacheInfo).Name %>" CommandName="ViewCache" text="View Cache" /> | |
</td> | |
<td style="text-align: right; width: 80px"> | |
<%# Sitecore.MainUtil.FormatSize((Container.DataItem as Sitecore.Caching.ICacheInfo).Size,false) %> | |
</td> | |
<td style="text-align: right; width: 80px"> | |
<%# Sitecore.MainUtil.FormatSize((Container.DataItem as Sitecore.Caching.ICacheInfo).MaxSize,false) %> | |
</td> | |
<td> | |
<div style="width: <%# PercentageUsed((Container.DataItem as Sitecore.Caching.ICacheInfo)) %>%; height: 30px; background-color: <%# PercentageColor(PercentageUsed((Container.DataItem as Sitecore.Caching.ICacheInfo))) %>; float: left;"></div> | |
<div style="width: <%# (100 - PercentageUsed((Container.DataItem as Sitecore.Caching.ICacheInfo))) %>%; height: 30px; background-color: #ccffcc; float: left;"></div> | |
</td> | |
</tr> | |
</itemtemplate> | |
</asp:Repeater> | |
</form> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment