We've got a very high traffic site, very badly written by the original agency - and it needs stupid amounts of hardware to keep it up and running.
When the Macro cache heats up the site is running fine - but publishes are happening literally every minute of the day so the cache is constantly flattened.
We've done some experiments around hacking the implementation of ICacheRefresher - but that means modifying the core and breaking the upgrade path.
I probably know the answer already - because the macro cache refresher is marked internal and discovered by reflection, but is there any way that we can hook into and override this without hacking the core.
Our idea - in the short term at least is to only clear the macro cache if it hasn't been cleared for an hour or so - sure content updates won't be instant but this is preferable to current performance.
Lastly, is there anything on the roadmap for a smarter Marco cache? I understand that it is really hard to programatically figure out which Macros a publish affects but one could for example - have config to indicate whether or not a certain doctype needs an instant refresh or could be deferred.
Also - rather than delete the key in question from the Macro cache, could it be queued to be built async and not impact the front end users?
The Macro ICacheRefresher isn't told why it is being refreshed when a publish occurs, just to drop the whole Macro cache.
So it is quite hard to do anything smart.
The only feasible ammend that I guess I could make right now is to check the last time that the Macro cache was cleared and if it was too recent, defer this clear to a future time period (configurable) using some kind of scheduled task.
One could also develop the logic that certain macros are not dumped immediatly (via config). The default is that they are, but for very expensive Macros (e.g. one that connects to an external web service) an additional setting on the Macro could say that this is only dumped from the cache every 10 minutes regardless of content publishes.
Thinking about it - I guess there are three types of Macro.
External data
Navigation (breadcrumb, footer links, left nav etc)
Listing out content - child nodes, descendants, widgets etc.
Only the top one is a real candidate for not being instantly dropped from cache - otherwise navigation etc becomes out of date. I think the "do not drop from the cache for 10 minutes no matter what switch" would still be a good one for developers in our situation. I'll hack around.
An easier thing to hook into is maybe a publish event that defers publishing - so that it doesn't happen instantly, but rather in batches - every few minutes.
I think you're trying too hard. Would the tried-n-true time-honoured 'FeedCache' be the solution here for your (slow) external data retrievals? You might recall that excellent package (in need of an update, hint hint)... http://blog.darren-ferguson.com/2008/6/14/feed-cache-package-for-umbraco/
No hacking the core. No upgrade problems. Force the local feedcache to update async or on a schedule.
You are probably right. There is even a feed proxy in the core just now.
I think what I've written is too much of a brain dump in fact.
The problem we have right now is a badly written site, which needs to be rewritten - and I'm looking for a plastercast to buy us time to do the rewrite.
I think we'll temporarily hack the core so Macros just expire after a period of time rather than on publish for now!
Hacking the core can't be a good plan even in the short term, can it? Having macros expire on a schedule is okay if you're only adding content, but if, for instance, a page name or location changes (and thus it's url) or a page is deleted having macros for nav, sitemap, etc. will cause broken links and bad visitor experience. That's scary to me. But you know what the content editors are doing and maybe that's not a legitimate concern for this site.
Honestly, if the biggest problem is expiring caches for remote call that have latency then something like a feedcache would be simple to implement... just change the url of the request to a local one in the macros. Then update the files on disk every hour or so. Even if the core of umbraco still wipes the cache on every publish there will be no significant delay in reading the data from a local source and your performance problem decreases significantly. It seems the sanest solution and also easy to implement. And your nav macros will still be resilient to changed links and deleted pages.
My £0.02 worth.
Let us know what you finally decide and how it works out for you.
A Smarter Umbraco Macro cache?
Hello All,
We've got a very high traffic site, very badly written by the original agency - and it needs stupid amounts of hardware to keep it up and running.
When the Macro cache heats up the site is running fine - but publishes are happening literally every minute of the day so the cache is constantly flattened.
We've done some experiments around hacking the implementation of ICacheRefresher - but that means modifying the core and breaking the upgrade path.
I probably know the answer already - because the macro cache refresher is marked internal and discovered by reflection, but is there any way that we can hook into and override this without hacking the core.
Our idea - in the short term at least is to only clear the macro cache if it hasn't been cleared for an hour or so - sure content updates won't be instant but this is preferable to current performance.
Lastly, is there anything on the roadmap for a smarter Marco cache? I understand that it is really hard to programatically figure out which Macros a publish affects but one could for example - have config to indicate whether or not a certain doctype needs an instant refresh or could be deferred.
Also - rather than delete the key in question from the Macro cache, could it be queued to be built async and not impact the front end users?
This is Umbraco 6.2.4 btw.
Thanks for any thoughts
More thoughts.
The Macro ICacheRefresher isn't told why it is being refreshed when a publish occurs, just to drop the whole Macro cache.
So it is quite hard to do anything smart.
The only feasible ammend that I guess I could make right now is to check the last time that the Macro cache was cleared and if it was too recent, defer this clear to a future time period (configurable) using some kind of scheduled task.
One could also develop the logic that certain macros are not dumped immediatly (via config). The default is that they are, but for very expensive Macros (e.g. one that connects to an external web service) an additional setting on the Macro could say that this is only dumped from the cache every 10 minutes regardless of content publishes.
Thinking about it - I guess there are three types of Macro.
External data
Navigation (breadcrumb, footer links, left nav etc)
Listing out content - child nodes, descendants, widgets etc.
Only the top one is a real candidate for not being instantly dropped from cache - otherwise navigation etc becomes out of date. I think the "do not drop from the cache for 10 minutes no matter what switch" would still be a good one for developers in our situation. I'll hack around.
:)
An easier thing to hook into is maybe a publish event that defers publishing - so that it doesn't happen instantly, but rather in batches - every few minutes.
Hi, Darren,
I think you're trying too hard. Would the tried-n-true time-honoured 'FeedCache' be the solution here for your (slow) external data retrievals? You might recall that excellent package (in need of an update, hint hint)... http://blog.darren-ferguson.com/2008/6/14/feed-cache-package-for-umbraco/
No hacking the core. No upgrade problems. Force the local feedcache to update async or on a schedule.
cheers,
doug.
Hey Doug,
You are probably right. There is even a feed proxy in the core just now.
I think what I've written is too much of a brain dump in fact.
The problem we have right now is a badly written site, which needs to be rewritten - and I'm looking for a plastercast to buy us time to do the rewrite.
I think we'll temporarily hack the core so Macros just expire after a period of time rather than on publish for now!
Hacking the core can't be a good plan even in the short term, can it? Having macros expire on a schedule is okay if you're only adding content, but if, for instance, a page name or location changes (and thus it's url) or a page is deleted having macros for nav, sitemap, etc. will cause broken links and bad visitor experience. That's scary to me. But you know what the content editors are doing and maybe that's not a legitimate concern for this site.
Honestly, if the biggest problem is expiring caches for remote call that have latency then something like a feedcache would be simple to implement... just change the url of the request to a local one in the macros. Then update the files on disk every hour or so. Even if the core of umbraco still wipes the cache on every publish there will be no significant delay in reading the data from a local source and your performance problem decreases significantly. It seems the sanest solution and also easy to implement. And your nav macros will still be resilient to changed links and deleted pages.
My £0.02 worth.
Let us know what you finally decide and how it works out for you.
cheers, doug.
Ultimately we'll rewrite the logic as Views that are quick.
Have a client discussion tomorrow
But you are right, a delete or an unpublish would have to clear the cache otherwise you end up with dead links - which is unacceptable.
We'll see how the meeting goes.
is working on a reply...