I was reading David Hayden's blog about this subject and that reminded me of something we did for our Plumtree install. In Plumtree, like Sharepoint Portal, you can have pieces of code called Portlets that are unique to the individual. We originally setup the default caching like David described but since each portlet was unique to the individual when we cached a single object it would display to users that it wasn't meant for. So, what was our fix?
We used Caching Versions of a Page, Based on Custom Strings. The custom strings we used from the Plumtree headers were "PT-User-Name" and "PT-Gadget-ID". We combined those together to create the key and cache it for an hour.
- To cache multiple versions of page output declaratively, based on custom strings
- In the .aspx file, include an @ OutputCache directive with the required Duration and VaryByParam attributes. The Duration attribute must be set to any integer greater than zero. If you do not want to use the functionality provided by the VaryByParam attribute, set its value to None.
In the body of the @ OutputCache directive, include the VaryByCustom attribute that is set to the string that you want to vary the output cache by. The following directive varies the page output by the custom string.
- In a code-declaration block in your application's Global.asax file, override the GetVaryByCustomString method to specify the behavior of the output cache for the custom string.
public override string GetVaryByCustomString(HttpContext context, string arg)
{
char delimiter = ';';
string[] args = arg.Split(delimiter);
StringBuilder result = new StringBuilder();
string config = context.Request.ServerVariables["HTTP_CSP_GATEWAY_SPECIFIC_CONFIG"];
for (int i = 0; i < args.Length; i++)
{
if (config != null)
{
int keyIdx = config.IndexOf(args[i]);
if (keyIdx > -1)
{
int keyValueLen = config.IndexOf(',', keyIdx) - keyIdx;
string keyValue = config.Substring(keyIdx, keyValueLen);
result.Append(keyValue);
result.Append(';');
}
}
}
return result.Length > 0 ? result.ToString() : null;
}
When the page in this example is requested with a different username a different version of the page output is cached for that user. So now each of these portlets will be cached for each user for an hour and we've seen a great increase in performance.