How to take advantage of server-side caching (Rack cache) without using browser caching

Visto 39 veces
Saltar al primer mensaje no leído

Wes Gamble

no leída,
5 mar 2011, 18:38:355/3/11
a radia...@googlegroups.com
I need to gain a deeper understanding of how the Radiant (Rack) cache works in order to solve a performance problem.

PROBLEM: I've created a sidebar in my app. which traverses the entire tree of pages using Radius tags in order to render - it basically generates a tree view of the published page hierarchy.  This is extremely slow, however, and takes on the order of 6-10s to render. I can set up standard Radiant caching to be some amount of time, but for each user's _first_ request, the entire page is re-rendered (2nd - N requests are cached locally in the browser and return just fine).

I have read through the Radiant::Cache class, and if I understand correctly, the SiteController.cache_timeout value is used to set the "Cache-Control" response header's "max-age" attribute. But the behavior that this appears to exhibit is that the first request is still a full render, and then subsequent requests pull from the local browser cache.

PREFERRED WORKAROUND: Obviously, I need to improve the performance of the rendering of the sidebar, but I'd like to try and have a workaround for now.

I wrote a cron job that requests all of the pages of the site in order to load up the Rack cache on the server, and then allow new clients to the site to be able to take advantage of that server side caching. But still, for any user, that first request still takes as long as a full render.   I've verified that the Rack cache appears to be filling up on the server.

QUESTION: Why doesn't the page get served from the server side Rack cache when a new user request a page that has been loaded into the Rack cache?  Is it because the default Etag calculation logic in Rails involves a full re-render of the page in order to calculate the Etag?

QUESTION: Is the current caching scheme in Radiant (Rack) completely dependent on client-side caching, implying that a given user _must_ do a full render before any caching benefits are realized?

I am looking at using this: https://github.com/mokisystems/radiant-fragment-cacher to cache the sidebar when it's created, and am pretty sure that this will satisfy separate user requests.

Thanks,
Wes

William Ross

no leída,
8 mar 2011, 10:37:168/3/11
a radia...@googlegroups.com
On 5 Mar 2011, at 23:38, Wes Gamble wrote:

I need to gain a deeper understanding of how the Radiant (Rack) cache works in order to solve a performance problem.

PROBLEM: I've created a sidebar in my app. which traverses the entire tree of pages using Radius tags in order to render - it basically generates a tree view of the published page hierarchy.  This is extremely slow, however, and takes on the order of 6-10s to render. I can set up standard Radiant caching to be some amount of time, but for each user's _first_ request, the entire page is re-rendered (2nd - N requests are cached locally in the browser and return just fine).

I have read through the Radiant::Cache class, and if I understand correctly, the SiteController.cache_timeout value is used to set the "Cache-Control" response header's "max-age" attribute. But the behavior that this appears to exhibit is that the first request is still a full render, and then subsequent requests pull from the local browser cache.

PREFERRED WORKAROUND: Obviously, I need to improve the performance of the rendering of the sidebar, but I'd like to try and have a workaround for now.

I wrote a cron job that requests all of the pages of the site in order to load up the Rack cache on the server, and then allow new clients to the site to be able to take advantage of that server side caching. But still, for any user, that first request still takes as long as a full render.   I've verified that the Rack cache appears to be filling up on the server.

QUESTION: Why doesn't the page get served from the server side Rack cache when a new user request a page that has been loaded into the Rack cache?  Is it because the default Etag calculation logic in Rails involves a full re-render of the page in order to calculate the Etag?

In testing you may not be seeing the standard public behaviour. Rack::Cache is (by default) configured to pass through any request with a Cookie: header, which means that a logged-in admin user will never hit the cache even on the published site. I've changed that recently in edge, so that the admin interface is explicitly uncached and the cookie header can be ignored. Nothing has blown up yet, but it still might.

QUESTION: Is the current caching scheme in Radiant (Rack) completely dependent on client-side caching, implying that a given user _must_ do a full render before any caching benefits are realized?

No. The default cache timeout is only five minutes, though. I normally increase that to at least a week. During the timeout interval you should only be rendering the page once.

I have been wondering about putting a 'cacheable?' flag on snippets and perhaps even rendering them on save if that flag is set. It feels a bit overcomplicated, though. The time would probably be better spent making radius less slow in the first place.

best,

will

Wes Gamble

no leída,
8 mar 2011, 11:18:328/3/11
a radia...@googlegroups.com
William,

Thanks for your reply.
Even that one time is too much because it results in a ~10s page load.  In the meantime, I have implemented the fragment cache extension (which although it was last updated for Radiant 0.8, works fine in 0.9.1) to cache these slow-rendering snippets. 

I think you've answered my question, in that it appears that Rack::Cache is only "pre-configured" to handle freshness based client side caching, and although you _could_ use it for server side caching, Radiant isn't set up out of the box to do that.  I am still looking into it.  The default Etag behavior implemented by Rails and Rack::Cache seems to only save you response transmission time on a cache hit, which doesn't seem like a particularly big win (if I understand correctly).

Agreed on making Radius less slow - if I have time, I will look at it.

Wes

William Ross

no leída,
9 mar 2011, 3:35:469/3/11
a radia...@googlegroups.com
A successful Rack::Cache hit is a big win. A cache hit should reduce your response time to little more than webserver delays and in a relatively static radiant site with a long cache lifetime that's what you get. 

That's really the situation for which radiant is ideal. As soon as you move away from a simple publishing scenario it gets more strained, and if you introduce any degree of personalisation or responsiveness you're thrown back on the basic rendering machinery. As you've found, it's not optimised for speed. That's the price of flexibility: there is no determinate way to work out which pages are invalidated by changes to a particular object, so we can't render at save and there is no shortcut to an etag or even a last-modified date. We just have to render the page.

Agreed on making Radius less slow - if I have time, I will look at it.

The good news there is that Radius development can proceed independently of radiant's release programme. The bad news is that the only real speedup will come from rewriting the ragel machine definition to emit C instead.

best,

will









rosslaird

no leída,
9 mar 2011, 11:46:299/3/11
a Radiant CMS
I can find various online postings and tutorials about increasing the
cache in rails, but is there a conventional way to do this in Radiant?
In other words, how do you do this:

> The default cache timeout is only five minutes, though. I normally increase that to at least a week.

Ross

William Ross

no leída,
9 mar 2011, 12:15:079/3/11
a radia...@googlegroups.com


The governing variable is SiteController.cache_timeout, and one common place to set it is in config/environment/production.rb:

SiteController.cache_timeout = 24.hours

best,

will

Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos