Skip to content

Instantly share code, notes, and snippets.

@jermdavis
Last active March 31, 2025 03:34
Show Gist options
  • Save jermdavis/fc4c8004ba1bd21540c8d2561ae4b279 to your computer and use it in GitHub Desktop.
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)
<%@ 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