If you’re working on SDL Tridion projects, having a solid understanding of the CoreService API is super beneficial. Whether it be generating reports for Tridion items, scripting updates of a large sets of items or building custom APIs on-top of the CoreService API to be integrated with GUI clients. For expensive operations, such as generating reports – I always end up looking for ways to cache the reports so I don’t have to wait 10-15 minutes each time I want to access the report.
I used to use some in-memory caching libraries, but I always had a couple of issues with the approach. Let me explain.
Why not use a simple in-memory cache?
One of the reasons I’m not super fond of using an in-memory cache library is because during development, the cache is still stored on the local developer machines. If you have 3-4 developers running Visual Studio with clients connecting to Tridion while developing the report functionality, even if the generated reports are cached in-memory, that still means each developer has to run the report to store it in-memory.
If we’re caching the objects returned from the Content Management server in-memory in Visual Studio, it still requires each developer to run the report once the cache expires. We want to cache the report at the Content Management Server side of things.
So how can we do better?
We’re looking for a way to cache the reports, but to make that cache available across local development machines. If a report takes 15 minutes to run, it’d be nice to be able to just pull the report instantly and be able to trigger a re-run of the report on an as needed basis.
The final solution
We settled on storing the object in application data, which is stored in the Tridion Content Manager Database. We created two API endpoints; the first allows us to pull the report, which grabs it from appData and returns it, with the second endpoint being responsible for regenerating the report before saving it in appData. This approach allows us to “cache” the report in appData long-term, and also regenerate the report on an as-needed basis.
The real magic was to serialize the objects before storing them in appData via the CoreService client, and then deserialize them upon retrieval back into the original object. I shared the code that we use below as a GitHub gist.
Refreshing the cached objects
We setup a simple PowerShell script to hit our “regenerate this report” API endpoint, and setup the Windows Task Scheduler to hit the endpoint nightly – thus regenerating the report each night.
# Invoke a web-request which hits the API endpoint to retrieve the report and store it back in AppData Invoke-WebRequest -Uri "http://localhost/TridionAPI/api/cache/refresh" -UseDefaultCredential -TimeoutSec 1800 # Write an item to the Tridion Event Viewer log to indicate the cache was renewed Write-EventLog –LogName Tridion –Source “Tridion General” –EntryType Information –EventID 1 –Message "Loading Capabilities Map completed."
Using the Task Scheduler, it’s easy to execute the PowerShell script above on the schedule cadence you’re looking for.
The code is available on GitHub as a gist. The code outlines two functions to allow storing, and retrieving, any object into application data.
For our specific implementation, we use Microsofts ASP.NET WebAPI to create API endpoints, which then call the two functions above to store and retrieve objects.
I’m a 28 year old web developer from Halifax, NS. When I’m not throwing out random quotes from The Office, you can probably find me hacking away on my PC or spending time with my fiance and two year old Doodle. I’ve been focusing lately on React and Java EE but I can never avoid the temptation of a new technology. Always striving to get better.