Slide 1

Slide 1 text

By Thijs Feryn Let the application do the work Not the VCL

Slide 2

Slide 2 text

Hi, I’m Thijs

Slide 3

Slide 3 text

I’m @ThijsFeryn on Twitter

Slide 4

Slide 4 text

I’m an Evangelist At

Slide 5

Slide 5 text

I’m an at Evangelist

Slide 6

Slide 6 text

I’m a at board member

Slide 7

Slide 7 text

Previously on Varnish

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Varnish still considered a sysadmin responsibility

Slide 10

Slide 10 text

Developers Sysadmins

Slide 11

Slide 11 text

Architecture

Slide 12

Slide 12 text

When you respect HTTP

Slide 13

Slide 13 text

Collaboration & empathy AKA DevOps

Slide 14

Slide 14 text

Today

Slide 15

Slide 15 text

Twitter Bootstrap

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Don’t cache header

Slide 18

Slide 18 text

Cache footer until 31/12/2015 23:59:59

Slide 19

Slide 19 text

Cache for a day

Slide 20

Slide 20 text

Cache for an hour

Slide 21

Slide 21 text

Expires: Thu, 31 Dec 2015 23:59:59 GMT Cache-Control: s-maxage=86400 Cache-Control: s-maxage=3600 Cache-Control: no-cache, no-store, s-maxage=0

Slide 22

Slide 22 text

The Demo

Hello, world!

This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.

Learn more »

Slide 23

Slide 23 text

I’m a PHP guy

Slide 24

Slide 24 text

Silex micro- framework http://silex.sensiolabs.org

Slide 25

Slide 25 text

Twig templates http://twig.sensiolabs.org

Slide 26

Slide 26 text

The Demo {{ render_esi(url('nav')) }}
{{ render_esi(url('jumbotron')) }}
{% block content %}{% endblock %}
{{ render_esi(url('footer')) }}

Slide 27

Slide 27 text

The Demo {{ render_esi(url('nav')) }}
{{ render_esi(url('jumbotron')) }}
{% block content %}{% endblock %}
{{ render_esi(url('footer')) }}
ESI tags

Slide 28

Slide 28 text

The Demo
{% block content %}{% endblock %}
ESI tags

Slide 29

Slide 29 text

register(new TwigServiceProvider(), array( 'twig.path' => dirname(__DIR__).'/views', )); $app->register(new HttpFragmentServiceProvider()); $app->register(new UrlGeneratorServiceProvider()); $app->register(new SessionServiceProvider()); Init code

Slide 30

Slide 30 text

Base controller $app->get('/', function () use ($app) { $response = new Response($app['twig']->render('index.twig')); $response->setSharedMaxAge(3600); return $response; })->bind('home');

Slide 31

Slide 31 text

{% extends "layout.twig" %} {% block content %}

Heading

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

View details » a>

Heading

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

View details » a>

Heading

Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

View details » a>

{% endblock %}

Slide 32

Slide 32 text

Navigation controller $app->get('/nav', function () use ($app) { //+ ADD MORE SESSION LOGIC $response = new Response($app['twig']->render('nav.twig')); $response->headers->addCacheControlDirective('no-cache',true); $response->headers->addCacheControlDirective('no-store',true); return $response; })->bind('nav');

Slide 33

Slide 33 text

Slide 34

Slide 34 text

Jumbotron controller $app->get('/jumbotron', function () use ($app) { $response = new Response($app['twig']->render('jumbotron.twig')); $response->setSharedMaxAge(86400); return $response; })->bind('jumbotron');

Slide 35

Slide 35 text

Hello, world!

This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique. p>

Learn more »

Slide 36

Slide 36 text

Footer controller $app->get('/footer', function () use ($app) { $response = new Response($app[‘twig']->render('footer.twig')); $response->setPublic(); $response->setExpires( DateTime::createFromFormat( "m-d H:i:s",'12-31 23:59:59', new DateTimeZone('Europe/London') ) ); return $response; })->bind('footer');

Slide 37

Slide 37 text

© {{ "now"|date("Y") }} Company, Inc.

Slide 38

Slide 38 text

Full HTML returned, even without Varnish

Slide 39

Slide 39 text

How does it work?

Slide 40

Slide 40 text

vcl 4.0; backend default { .host = "127.0.0.1"; .port = "8888"; } sub vcl_recv { set req.http.Surrogate-Capability = “key=ESI/1.0"; return(hash); } sub vcl_backend_response { if (beresp.http.Surrogate-Control ~ "ESI/1.0") { unset beresp.http.Surrogate-Control; set beresp.do_esi = true; } } Simplified VCL

Slide 41

Slide 41 text

HttpFragmentServiceProvider

Slide 42

Slide 42 text

register(new \Silex\Provider\TwigServiceProvider(), array( 'twig.path' => dirname(__DIR__).'/views', )); $app->register(new Silex\Provider\HttpFragmentServiceProvider()); $app->register(new Silex\Provider\UrlGeneratorServiceProvider()); $app->register(new Silex\Provider\SessionServiceProvider());

Slide 43

Slide 43 text

{{ render_esi(url('nav')) }} Controller name URL generator ESI rendering

Slide 44

Slide 44 text

curl -H "Surrogate-Capability: key=ESI/1.0" localhost:8888/ Sends Surrogate- Control response header back to Varnish ESI

Slide 45

Slide 45 text

Internal subrequest curl localhost:8888/

Slide 46

Slide 46 text

All ESI tags could be replaced with AJAX calls

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

More Javascript

Slide 49

Slide 49 text

More async

Slide 50

Slide 50 text

Graceful degradation

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

ESI without Varnish

Slide 53

Slide 53 text

CDN

Slide 54

Slide 54 text

HttpCacheServiceProvider

Slide 55

Slide 55 text

register(new \Silex\Provider\TwigServiceProvider(), array( 'twig.path' => dirname(__DIR__).'/views', )); $app->register(new Silex\Provider \HttpCacheServiceProvider(), array( 'http_cache.cache_dir' => dirname(__DIR__).'/cache/', )); $app->register(new Silex\Provider\HttpFragmentServiceProvider()); $app->register(new Silex\Provider\UrlGeneratorServiceProvider()); $app->register(new Silex\Provider\SessionServiceProvider());

Slide 56

Slide 56 text

//$app->run(); $app['http_cache']->run();

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

No content