Full page cache and events

Permalink 3 users found helpful
Just few days ago I made a bug report wondering if it's a bug or feature that events defined in a package controller won't be fired when the page is cached by Full Page cache. It appeared that it actually is a feature and that on a full page cached page the package controllers are not "executed" which gives nice performance boost.

I'd like to know what would be the best place in a package to add some code that should be executed on every page load, be the page cached or not? What I mean here is something that would not have any effect on the page rendered, but rather to do something only on backend for example logging something. Would it require overriding/extending some core model(s)? Theme header/element is not possible in my case.

Any ideas on this one? What do you other developers think, should there be some kind of "hook" to which events could be attached, even if the page was cached?

Just to give an example, following code in a package controller won't fire on full-page cached page:
public function on_start() {
            $l = new Log('testing', true);
            $l->write(date('U'));
            $l->close();
    }

 
JohntheFish replied on at Permalink Reply
JohntheFish
Having a cache that bypasses the whole events system seriously hobbles the usefulness of the events system. This applies to both the page and block cache. What use is an event if you can't rely on it being fired?

At the moment, responses to post requests do not get cached. Personally, I would like pages that have some events to be treated in the same way.

EDIT - link to your bug report:
http://www.concrete5.org/developers/bugs/5-6-1/on_start-defined-in-...
JohntheFish replied on at Permalink Reply
JohntheFish
Thinking about this more, a solution that may suit all is to have an additional option in the Cache Settings on the dashboard, to delay the page cache decision until after the page is known. Perhaps placing it after the on_before_render event, as that is the first event handler that fires after a page is known.

That way, we could have the cache with a slightly higher response time instead of needing to leave it off completely when using events.
Ale replied on at Permalink Best Answer Reply
Good ideads.

One possible solution would be to have some spesific variable in package controller just like block controllers have the $btCacheBlockRecord that define if block output can be cached. Then at some point, for example when overrides cache is "filled up", system would check which package controllers are non-cacheable and mark them somewhere (database maybe?). This way the core would "know" which package controllers it has to execute regardless of cache settings. That however would require developers to add such rule to the existing packages.

Another option would be to check for system event functions with method_exists() on package install or update and mark the packages cacheable or not.

Someone already mentioned on the bug tracker page that this bug/feature effectively renders the Mnkras' Page Redirect attribute package unusable on fully cached pages.
JohntheFish replied on at Permalink Reply
JohntheFish
I don't know if there is a significant performance difference between testing for a variable and a method. However, as you point out, this would only need to be tested when the overrides cache is filled, so the last little bit of performance would probably not be critical.

I would be happy with either of your suggestions. (EDIT)- Either could remove any need for a dashboard setting - I suspect the difficult bit will be the actually moving of the cache decision to a different stage of the overall process and allowing a package to decide (given current page info) whether the cache can be used for that page.

Page redirect is I think a valid reason that this issue should be treated as a bug that needs to be fixed rather than a feature we have to learn to live with.
JohntheFish replied on at Permalink Reply
JohntheFish
I have started a new thread on the whole caching issue, bringing together points from a range of other threads (inc this one)

http://www.concrete5.org/developers/pro-accounts/community-leaders-...
Ale replied on at Permalink Reply
Ok, thanks for the info. It appears that the thread is under community leaders' forum and I'm unable to access that part of the forums. Could be an interesting thread to read :)
fivedust replied on at Permalink Reply
fivedust
Can't access this thread and would like to know if anybody else has built a way around it. Ideally there would be a system provided on_before_cacheevaluate event or something, in the meantime I wonder what would be the best way to go around that restriction ( bug ). Anyone?
JohntheFish replied on at Permalink Reply
JohntheFish
On a Totally Random last autumn Franz & Andrew committed to providing discrete control of block caching at page or block level. However, such control is not in 5.6.3.

As for the page cache and events, the conclusion by Andrew from the leaders thread was that full page cache effectively saves a page as static html and there would not be any revision of the full page cache to support events. No one else on the thread was happy about that, but that is unfortunately the way it is.

My approach to designing event related functionality has consequently changed to do more by ajax and less by php. If an ajaxing javascipt gets cached with its page, the script still runs on the browser.
fivedust replied on at Permalink Reply
fivedust
Thanks John. Was thinking about Ajax, too. Unfortunately in this specific case I need to check if an incoming URL carries tracking vars to internally track, strip and redirect to a url without those vars. Something that is not doable via ajax when the premiss is to hide that process from users's eyes. There are plenty of other scenarios where not being able to fire/catch pre cache events is pretty much a breach of expected system behaviour. Now I guess I have to prepend a small footprint script somewhere before the page cache get evaluated. Not ideal, but what choice do we have...