18

I am using the cache tag in my templates. How can I assure that a site visitor always gets the data directly from the cache and never has to wait for it to be generated?

My cache gets invalidated quiet often, as this happens each time new content is created or edits are made.

Any idea on how to trigger the recreation of all cached template content automatically?

.

Edit:

To better explain my use case: some of my craft.assets and craft.entries calls result in a lot of DB queries. Without the template being cached this leads to 3+ seconds delay in page-load. Using Craft cache this is solved for all but one site visitors, because there is still the first visitor, that has to trigger the caches to be created.

I think you shouldn't ignore this single user and hope someone comes up with a solution as additional 3+ seconds in page-load can easily cause customer loss. Further I'd appreciate a solution feasible with core functions, as I consider performance being a key component to every site.

.

2nd Edit:

The reason I started a bounty on this question was to get more attention on it from the community and also from P&T. This seems to work out so far, so thank you all for your thoughts on this and for having this interesting discussion, which is sometimes a little too technical for me (who's not a php/server developer). I actually don't know what to do which the bounty points, but for me it was already worth spending them (who cares for pts anyway?)!

  • 2
    I think it'd be ideal if a cached file never expired and the 'cacheDuration' config option was really just an interval in which the cached file was regenerated using a background action using something like yiiframework.com/extension/runactions. This way, every user is served a cached file of some sort except user who hits the page for the very first time. – Wes Rice Jun 20 '14 at 0:01
  • 1
    Why not a plugin that empties the cache and crawls the front end to re-trigger caching, tied to cron? – Matt Stein Jun 24 '14 at 16:59
  • 2
    @Brad I don't want it to be not invalidated, but I want the caches to be updated directly on invalidation without a site visitor to trigger it and thereby has to wait for the creation. – carlcs Jun 24 '14 at 22:12
  • 1
    This is a tricky topic, but one that I have found to be a frequent request with heavily cached sites. CE Cache (ExpressionEngine), has an option "refresh" cache upon clearing, asynchronously. Ideally how I think this should work is: – Tim Kelty Jun 25 '14 at 13:18
  • 1
    Ideally, how I think this should work is: * Cache is determined to be expired * Before the cache is deleted, a request is made, somehow qualified to get the un-cached copy, while the normal, public-facing request stays cached. * Once the new data is received, replace the existing contents. In theory, this should allow for cache expiration and refreshing without any un-cached downtime. However, I've yet to see a system that works like this. – Tim Kelty Jun 25 '14 at 13:24
4

I built the Cache Warmer plugin recently, which takes a blanket approach to refreshing your pages cache, by getting entries url with the .getUrl() method, and then send of batch requests to those url's.

I'm currently using it together with the Cache Clear plugin, when deploying changes to our site, and it's working well. This is a very simplistic approach to a potentially complex problem, so I would say a more granular cache invalidation/refresh strategy might be needed, depending on your use case.

However, I think there is something to be said for this approach on small to medium sites.

I want to at least add some hooks, so that you can warm up single entries/elements as well. My plugin doesn't know which pages your cached elements are living on, but there is a big chance those pages will be hit and warmed up - as long as they're located in a section, and that section is toggled in the plugin settings.

2

I do not believe that this is a feasible feature request. Cache Invalidation isn't checked until Twig checks for it when it encounters the cache tag. If the content being cached is rarely updated, you can instead set the cache expiration date to something far off. Maybe something like {% cache for 3 years %}.

  • "this happens each time new content is created or edits are made" != "because I set my cache duration to 1 day" – carlcs Jun 22 '14 at 22:38
  • This is true. If you look at TemplateCacheService.php it shows the functions that wipes caches base on Element Type and Element ID. It also runs it on each request. To rebuild caches, you would need to create a task that runs a pretend page request for each cached path. But that wouldn't change how the rest of the cache system works. It would still refresh based on his config, because their cache system is base on Yii's cache system. I can point out the files if you want to look at how it's all put together. I welcome a correction from P&T because they would clearly know better than I. – Bryan Redeagle Jun 22 '14 at 23:10
  • I definitely don't want P+T to change how the complete cache system works. Just looking for an answer on how to get rid of any delays site visitors may encounter because of invalidated caches. – carlcs Jun 24 '14 at 10:24
  • 3
    "If you can imagine this being a plugin, why do you think this shouldn't go into Craft core?" - I can imagine a lot of things in a plugin and 99.999% of them shouldn't be in core. – Brad Bell Jun 24 '14 at 21:45
  • 1
    Not sure why you put a 200 pt. bounty on it unless hoping to shake something out of a tree. I would think such a plugin would need to be intelligent, possibly holding_off changes to avoid load during busy hours, and updates all in the middle of the night if you have one for span of site visitors. You see this reverses what you ask for, but may be a better strategy. I would hope for no naive plugins on a thing like this. Maybe another approach would be to put up an auto-takedown alert 'Site refreshing, will show in a moment' if you can afford busy-time update delays at all? – narration_sd Jun 25 '14 at 2:03
1

I have a plugin that clears the cache from outside the control panel, I'm sure its possible to rebuild the cache using the same type of approach. Here is a link to my plugin if you need a starting point.

https://github.com/themccallister/craft.cache-clear

Without looking at the code, it may be possible to clear the cache and then immediate build it.

However, I agree with the majority that this should NOT be a core feature of Craft. Craft is focused on content and extensibility so adding more and more to the core is not in their, or our, best interest.

  • Thanks for your ideas! And I totally agree, the focus on a select group of features is one of the reasons I love Craft so much. We definitely don't need any bloat! Bloat's what plugins are for. ;) But caching is one of those features already built into core. P&T have chosen to provide each Craft install caching functionality out of the box. A decision I really appreciate, because it makes it easy for inexperienced users (like I am one) to get a performant site up and running. – carlcs Jun 25 '14 at 20:43
  • Now that caching belongs to the core, I think that it is in the interest of P&T to make this work great (and flexible!). It's good as it is today, but it can certainly be improved in one way or another, and I actually have little doubts that caching will not be further developed down the road (Craft's is just 1 year old!)! – carlcs Jun 25 '14 at 20:45
0

I just came across this feature request on http://feedback.craftcms.com/ and I think this is pretty much the feature I had in mind when asking the question:

Add lazy cache rebuilding to the cache tag

PS: please don't upvote this answer, but do so on the feature request. :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.