nexcess / magento-turpentine

A Varnish extension for Magento.
GNU General Public License v2.0
520 stars 253 forks source link

Layout Caching and ESI Blocks #272

Open joewoodhouse opened 11 years ago

joewoodhouse commented 11 years ago

Hiya,

I haven't totally got to the bottom of this issue yet, but I think there might be a problem around ESI block caching with magento Layout Caching enabled.

Basically my site has both a mobile and a desktop version. What I'm seeing is if a page - say the home page - is visited first by a mobile user, and then it is visited by a desktop user, the header becomes corrupted.

From debugging I've seen that the layout being applied is a cached copy of the layout generated from the mobile visit, so I'm getting this horrible case where the right templates are being used (desktop) but the wrong layout (mobile). Obviously the reverse will be true - whichever user agents views the site first will have their layout cached and corrupt the other user agents view of the block when ESI'd.

Quite possibly what I'm doing is stupid - I'm no Magento expert. My current workaround is to just disable Layout Caching in the configuration. However obviously this isn't ideal as now I have to tell my client that whilst cached portions of their site are faster, the non-cached portions are now marginally slower (possibly it's not even detectable - I've not profiled it yet).

Anyone have any thoughts/comments/guidance?

aheadley commented 11 years ago

Can you try enabling the Normalize User Agent option?

joewoodhouse commented 11 years ago

Yea I've tried with that enabled and disabled, makes no difference.

I've studied the logs out of varnish (varnishlog) and can see that the User Agent is being correctly picked up as different both times it loads the header block (one for mobile, one for desktop).

I've been through the code debugging/printing and I'm pretty sure the problem comes at the Magento side. With layout cache enabled, when it loads the header block for the 2nd request the cache index for the layout will be the same and it will be loaded from cache (this occurs in Mage/Core/Model/Layout/Update.php function load). So the wrong layout will be used even though the right templates seem to be used.

aheadley commented 11 years ago

Just to be sure, can you try disabling Turpentine and Varnish to make sure it's not an issue with your Magento setup?

joewoodhouse commented 11 years ago

Yea I've done that several times - everything works as expected if Varnish is disabled.

roed commented 11 years ago

Same issue here.

We also have a mobile theme, and the header layout (navigation etc) gets corrupted on desktop, after a mobile user visited the page. This only happens when layout caching is enabled. When we disable the cache, the mobile and the desktop sites work fine.

The 'Normalize User Agent' setting doesn't change anything. We tried both.

It is as if the esicontroller.php cannot determine the right layout.

ollieno commented 11 years ago

Hi @aheadley, @joewoodhouse and my dear college @roed

Any news on this issue yet?

csdougliss commented 11 years ago

We get the same problem but with the footer

shaily-a commented 10 years ago

Any help on the issue? Facing the same problem.

nvingenieria commented 9 years ago

I know this is an ooold thread but I'm facing the same problem and after an investigation I have found a fix that work for me.

The problem is in the method Nexcessnet_Turpentine_EsiController::_getEsiBlock.

You'll find this line: $layoutUpdate->load($this->_swapCustomerHandles($esiData->getLayoutHandles()));

Debuging the call to $layoutUpdate->load(), the parameters passed was something like this:

2015-03-25T15:22:57+00:00 DEBUG (7): Array ( [0] => customer_logged_out [1] => default )

These are the handles of the layout that must be loaded to serve this request (generate the ESI block), but if you load any page in your shop and log the handles passed to $layoutUpdate->load(), you will see something like this:

2015-03-25T15:22:57+00:00 DEBUG (7): Array ( [0] => customer_logged_out [1] => default [2] => THEME_frontend_mymobilepackage_mymobiletheme )

So, there is a missed handle when the ESI block is generated. This means that the (cached) layout used to server the esi block request will be the one for the default theme in your shop, and not the one for the mobile theme.

Modify the line to this:

$package = Mage::getSingleton( 'core/design_package' ); $handles = $this->swapCustomerHandles($esiData->getLayoutHandles()); $handles[] = 'THEME'.$package->getArea().''.$package->getPackageName().''.$package->getTheme('layout'); $layoutUpdate->load($handles);

And it should work... At least is working for me ;)

aricwatson commented 9 years ago

This PR https://github.com/nexcess/magento-turpentine/pull/579 appears to be useful and we're evaluating it. Please let us know if it solves your problem.

LyndonHook commented 9 years ago

Above PR updated to devel branch on request. It can now be found at https://github.com/nexcess/magento-turpentine/pull/955

miguelbalparda commented 9 years ago

@joewoodhouse I just merged #955 into devel, can you check and let us know if this fixed your issue?