Orchard caching

Topics: Customizing Orchard, Writing modules
Sep 30, 2013 at 4:58 AM
Hi,

I've read https://orchard.codeplex.com/discussions/436874 and http://docs.orchardproject.net/Documentation/Caching (which came out of the former) and this https://orchard.codeplex.com/discussions/274921

In my case, all the pages of the site contain some dynamic parts which are implemented as widgets and gets data from the db according to authenticated user. However, I want to find out what I can do to improve performance.

Since the site is not on a farm for now, I use settings cache in my module to store some query results without problem. These statistical queries are heavier than others and cache is invalidated daily.

My questions are:
1- Does using OutputCache module make sense at all in the case of those dynamic widgets dependent on current user?
2- Is there a module in the gallery to achieve so called donut hole caching?
3- Does it make sense to change OutputCache to use the requesting user (including anonymous user) as a part of cache key (if opted so in cache settings)? If so, is it possible to do this without touching the OutputCache module, suppressing stuff (magic!)?
4- Although this site is not running on a farm, would Memcached module(s?) provide anything good? I'm asking this mostly because once Sebastien wrote (in the third link above):
Memcache module
There is the Cache module which is currently available on the forum. I personally made this one, and I already know how I will improve it, by handling donut caching.
5- Is there a negative side affect I'm missing of using settings cache for storing non-setting data, when it's not on a farm solution?

Thanks in advance.
Coordinator
Sep 30, 2013 at 7:03 AM
  1. No, unless you bring those widgets after the initial hit using ajax.
  2. No. It was never implemented that I know of.
  3. Yes, you could vary by user with little effort, but the problem with that approach is that you'll have one cache entry per user, which almost always defeats the purpose of caching: the cache efficacy is then very low, and it's going to run out of memory, and will need to recycle entries, much faster.
  4. I don't think memcached makes any difference. Donut caching could be implemented independently of the underlying cache implementation, as far as I can tell.
  5. When not on a farm, I don't think so, but that means that what you do can't be shared, and won't be usable if you ever need to move to a farm.
Sep 30, 2013 at 9:56 AM
Edited Sep 30, 2013 at 10:28 AM
We made a custom donut hole caching 'system' based on https://github.com/moonpyk/mvcdonutcaching

Maybe you could look into doing the same?

edit: Fixed the url
Developer
Sep 30, 2013 at 6:55 PM
Donut caching is something we've been discussing for a very long time, but haven't come to a conclusion on how to actually implement it yet.

Looked briefly at your solution and it's not applicable to Orchard, at least not directly. You're strongly relying on @Html.Action, whereas Orchard discourages the use of it in favor of using shapes/partials to construct the entire page from a single action. Extensive use of @Html.Action and @Html.RenderAction will hurt performance a lot (eg. causing all filters and all related events to fire multiple times during a single request) and complicate things when it comes to debugging.
Sep 30, 2013 at 10:48 PM
Edited Sep 30, 2013 at 10:52 PM
pszmyd wrote:
Donut caching is something we've been discussing for a very long time, but haven't come to a conclusion on how to actually implement it yet.

Looked briefly at your solution and it's not applicable to Orchard, at least not directly. You're strongly relying on @Html.Action, whereas Orchard discourages the use of it in favor of using shapes/partials to construct the entire page from a single action. Extensive use of @Html.Action and @Html.RenderAction will hurt performance a lot (eg. causing all filters and all related events to fire multiple times during a single request) and complicate things when it comes to debugging.
Well, you guys keep on discussing it, while we, a real world user, have a working solution ;)

Btw, it is exactly this kind of "our way or no way" mind set that makes us not want to even attempt open up our custom code to the world, as it would never fit the 'Orchard' story (or at least, that is the vibe that we are getting)

Having a choice is better than having none. Not the best way may still be a good way.
Developer
Sep 30, 2013 at 11:59 PM
Edited Oct 1, 2013 at 12:01 AM
We're real-world users as well, building stuff on Orchard for our clients!;)

The whole problem with implementing a thing like donut caching (and lots of others) in the Orchard core is that it needs to fit the design, guidelines, and most importantly, be as unobtrusive as possible. So you could turn it on, configure, tweak some things and it will just work. Without having to rewrite the whole app using some new conventions.

I haven't said that your solution is bad - if it works for you then it would probably work for others. Just saying that it's written in a way that does not play well with Orchard core design. It surely can be made a module that lots of devs could benefit from if they're ok with using @Html.Action. Having a choice is always good, I agree 100%.
Coordinator
Oct 1, 2013 at 12:13 AM
We don't have the same constraints, and that's good. You can decide to change the core on your own instance thanks to open source. What you could do though is to publish your recipe in a blog post for instance so that we could refer to it if people are asking. Chris Bower had done a similar solution for Shapes two years ago, you can still find it if you google for it, and they were pretty happy with the result,
Developer
Oct 1, 2013 at 12:20 AM
Exactly. That's the beauty of open-source:)

Btw - if I recall correctly Chris has been working on a very high-traffic site - http://aclj.org/ - if they were happy with the result it had to be good. Not sure about the version, but it may still be applicable to 1.7 with a few changes.
Oct 1, 2013 at 12:25 AM
Bertrand, thanks for the explanations and ajax tip. I guess I can redesign authenticated user related bits to be rendered using ajax calls if there will be complaints.

AimOrhcard, thanks for the suggestion. In the current project I'm not in a position to put in more hours to implement such solutions. You see, we didn't think about caching at the beginning and now we will do little effort touches here and there, like enabling and configuring a module. But I will keep this one in mind for future projects.

Piotr, would this play well with core: an OutputCache setting to decide "Cache only anonymous requests", putting a VaryByCustom call in the OutputCache module, introducing a dependency/extensiton point like ICustomCacheVaryProvider (hell of a name) implementing GetVaryByCustomString in global.asax to get the string by looping through any providers, and implement the default provider in OutputCache? I'm not even sure if this would work, but I wonder if a pull request playing around with global.asax would go the core.

And thanks Sebastien, I will google shape caching.



Coordinator
Oct 1, 2013 at 12:41 AM
You can't cache authenticated content as you could potentially share secured data, tokens, cookies, ... who knows.
Oct 1, 2013 at 1:10 AM
So does that mean OutputCache works this way (caches only anonymous requests) and requires no code change to achieve this?


Oct 1, 2013 at 6:59 AM
sebastienros wrote:
You can't cache authenticated content as you could potentially share secured data, tokens, cookies, ... who knows.
We cache authenticated content. But the 'per user' content is cached 'per user' and not globally.

Our solution also include a 'hack' to differentiate between pages requested by authenticated users and users who are able to 'edit' content (without it, regular users would get the 'Edit' links that got shown & cached if you would visit the page first with a user that has edit permissions).

That said: www.tacx.com feel free to inform me about any issue you found that is a result of how we cache things!
Coordinator
Oct 1, 2013 at 5:35 PM
@AimOrchard, this is ok. Please google for how Discuss is using caching w/ authenticated content, this is very interesting.