First-class support for ESI in Drupal: Lets Do It!

Events happening in the community are now at Drupal community events on www.drupal.org.
joshk's picture

Over the past few days some of us have been discussing the aims and ambitions of this project:

http://drupal.org/project/esi

There are a lot of pieces to be developed to support this properly. My aim is to get something simple in place to allow blocks, regions and panels to be served out of an ESI cache. There are further ideas to build some sort of ESI-assembly into the Boost module, and to implement an intermediary cache layer between Drupal and an external ESI cache (e.g. Varnish) to prevent multiple bootstraps.

So, let's take this discussion out to the wider community!

Comments

Gameplan

mikeytown2's picture

Quick Summery/Plan

  • Support the following replacement methods
    Server Side
    ESI - http://varnish-cache.org/wiki/ESIfeatures (get this working first, add in SSI, AJAX later)
    SSI - http://httpd.apache.org/docs/trunk/mod/mod_include.html

    Client Side
    AJAX - Steal code from boost to do this

  • Use esi.php either as a file or menu hook. File is so we can cache it (implement with a cache lifetime of 0 first, work on storage later).
  • Replacement of Blocks, Panels, Theme Hooks, Regions
  • Need to agree on a standard for calling esi.php and the security concerns with making a generalized way of getting chunks of html out of Drupal. Eventual support for JSON output.

I see the first alpaha of this module will have ESI, no cache, and the replacement of blocks or panels working.

Current interesting projects/code
http://drupal.org/project/authcache
http://drupal.org/project/ajaxify_regions
http://drupal.org/project/remoteblocks
http://drupal.org/node/657826#comment-2372308

In my ideal world, the

moshe weitzman's picture

In my ideal world, the talents here focus on a great solution for Drupal 7. I'd like to point out that we already got some ESI support in core for D7. See http://drupal.org/node/651902. What shall we do it? Lets build it out. If core needs more minor changes, we can try to get them in.

BTW, both examiner.com and Acquia Gardens are built on Drupal 7. These are very large, complex web apps. The future is here.

That's what we need!

joshk's picture

The patch here is like the one I got into Panels that allows ctools caching systems to alter the outgoing markup when a caching operation takes place. That's really the key element.

Beyond that, it's just a matter of creating the system to alter the output and then respond to the resulting request. I think that work should also translate pretty well to D7, and the important thing for D8 will be figuring out how to make Drupal bootstraps cheaper when we only need to generate a small bit of content.

Bit like ID design

dstuart's picture

So just as ID's build for firefox fix for IE. We should be doing "Build for D7 and patch for D6".

Because my client is still on D6 and its very unlikely they will move to D7 until its has sufficent contrib module coverage (and its been in the wild for about 6 months) I will need to do the D6 module.

Based on the core architecture changes would it be easy to backport this functionality or it a stand alone module better??

Cheers

Sounds like a good idea

joshk's picture

This is a good idea. I also have working implementations in D6 that need this, but I think we should build this with the future in mind.

Glad I could help connect

wim leers's picture

Glad I could help connect those with existing code and those who are interested in implementing it in a generic way :)

Let's make Drupal's ESI support kick ass :)

Playing around in D6

recrit's picture

I wanted to share some of my findings and testing in D6.

My goal was to test without patching / hacking core and focusing on blocks only. More or less, I was after a proof of concept, so this method is likely not suitable for anything future / scalable / deployable to users who don't really know why they want ESI. BUT it might spark some ideas or discussions on the future implementation.

The use case is for anonymous traffic with the page cached / varnished; therefore, as long as you rewrite the content of the block to an ESI tag when the page gets built, store some basic info to rebuild the object later in the menu callback, and be creative with the menu callbacks so you can target in your varnish default.vcl -- then once the page is cached everything is driven by varnish calling the esi callback paths.

Method

  1. Storing Data
    • hook_form_{block_add_block_form}_alter, hook_form_{block_admin_configure}_alter
    • store in db table: block bid, ttl
    • store in cache: block ttl and basic info to rebuild block on menu callback
  2. Page building
    • Override theme_blocks()
      • Override an entire region or target individual blocks
      • rewrite content with <esi:include src = "esi / {ttl} / {identifying info}"/>
      • Normal processing if not anonymous
    • Implement hook_preprocess_page()
      • Flag a page as having any esi, so you can target in vcl file to run esi; and disable any page compression [server or drupal] - see compression issue below
      • Collect all AJAX (ttl = 0) blocks into one $.getJSON call
  3. ESI Callback
    • hook_menu(): path includes ttl and some identifying - "esi / {ttl} / {identifying info}"
    • esi callback:
      1. Bootstrap Full
      2. Load block with identifying info
      3. Output content

Results

I added 3 blocks that output the current time - AJAX, ttl = 5s, and ttl = 15s (short times for dev). Hitting refresh a few times, you can see the magic take place as times change / don't change.

Caveats / Issues

  • Multiple Bootstraps - I believe this is the biggest hurdle to overcome. In my test above, there is a min of 1 bootstrap and a max of 3 - when the 5s and 15s blocks align. Using entire regions can help minimize the number of calls. Having different ttl blocks / regions could complicate any intermediate cache layer to minimize the calls.
  • Page compression with esi - this is currently not supported, so you have to turn off any compression when processing any esi - see http://varnish-cache.org/wiki/PostTwoShoppingList#a6.Gzipsupport

 

Hope this gets some discussions going. Playing around with the blocks, you can really see the power and possibilities that esi brings to the table.

Drupal.org + ESI?

bibo's picture

We all know Drupal.org uses Varnish (which lately seems to have generated some occasional connection fails, not for me only I assume?).
But, does anyone know if drupal.org uses ESI for authenticated users?

This slideshow linked to in this comment on the esi-module's issue queue seems to suggest it does. But maybe it's just an example on how it could be used?

I'm investigating ESI-usage for authenticated users for a really large Drupal site. The site has about 10x the nodes that Drupal.org does and over 10x the number of comments, and currently lives without any varnish at all.

drupal.org does not use ESI.

moshe weitzman's picture

drupal.org does not use ESI. Patches welcome :)

I know that this module was born just a month ago at Drupalcon and holds some of the most recent ESI work - http://drupal.org/project/esi_api

Thanks for your answer

bibo's picture

Thanks for your answer Moshe.

I looked at esi_api earlier, but it's for D7 only, and this particular D6 site can't be upgraded anytime soon. Too bad that the work on esi-module (for D6) don't seem to be progressing much. Will need to do lot's of custom code / vcl confs manually, I guess.

D6 ESI module is now on git

Ravi.J's picture

Hi,
Work on ESI module is currently being done on github. https://github.com/dstuart/Drupal-ESI-Module/network

-Ravi

High performance

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: