Skip to content

Commit 01df3e7

Browse files
committed
feature #4626 clean up cache invalidation information on the cache chapter (dbu)
This PR was merged into the 2.3 branch. Discussion ---------- clean up cache invalidation information on the cache chapter | Q | A | ------------- | --- | Doc fix? | yes | New docs? | no | Applies to | all | Fixed tickets | - The documentation on active cache invalidation is overly negative. I tried to make it more neutral and point to FOSHttpCacheBundle for further information. Commits ------- 0accf63 cleanup cache book chapter 979034a move fos httpcache bundle tip up to beginning of invalidation section 2bddbb1 move invalidation up into expiration and validation section d4d2236 clean up cache invalidation information on the cache chapter
2 parents ece2c81 + 0accf63 commit 01df3e7

File tree

1 file changed

+120
-68
lines changed

1 file changed

+120
-68
lines changed

book/http_cache.rst

+120-68
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,14 @@ its creation more manageable::
333333
// set a custom Cache-Control directive
334334
$response->headers->addCacheControlDirective('must-revalidate', true);
335335

336-
Public vs private Responses
336+
.. tip::
337+
338+
If you need to set cache headers for many different controller actions,
339+
you might want to look into the FOSHttpCacheBundle_. It provides a way
340+
to define cache headers based on the URL pattern and other request
341+
properties.
342+
343+
Public vs Private Responses
337344
~~~~~~~~~~~~~~~~~~~~~~~~~~~
338345

339346
Both gateway and proxy caches are considered "shared" caches as the cached
@@ -399,9 +406,10 @@ header when none is set by the developer by following these rules:
399406
``private`` directive automatically (except when ``s-maxage`` is set).
400407

401408
.. _http-expiration-validation:
409+
.. _http-expiration-and-validation:
402410

403-
HTTP Expiration and Validation
404-
------------------------------
411+
HTTP Expiration, Validation and Invalidation
412+
--------------------------------------------
405413

406414
The HTTP specification defines two caching models:
407415

@@ -418,7 +426,9 @@ The HTTP specification defines two caching models:
418426
header) to check if the page has changed since being cached.
419427

420428
The goal of both models is to never generate the same response twice by relying
421-
on a cache to store and return "fresh" responses.
429+
on a cache to store and return "fresh" responses. To achieve long caching times
430+
but still provide updated content immediately, *cache invalidation* is
431+
sometimes used.
422432

423433
.. sidebar:: Reading the HTTP Specification
424434

@@ -772,7 +782,7 @@ at some interval (the expiration) to verify that the content is still valid.
772782
annotations. See the `FrameworkExtraBundle documentation`_.
773783

774784
.. index::
775-
pair: Cache; Configuration
785+
pair: Cache; Configuration
776786

777787
More Response Methods
778788
~~~~~~~~~~~~~~~~~~~~~
@@ -800,8 +810,110 @@ Additionally, most cache-related HTTP headers can be set via the single
800810
));
801811

802812
.. index::
803-
single: Cache; ESI
804-
single: ESI
813+
single: Cache; Invalidation
814+
815+
.. _http-cache-invalidation:
816+
817+
Cache Invalidation
818+
~~~~~~~~~~~~~~~~~~
819+
820+
"There are only two hard things in Computer Science: cache invalidation
821+
and naming things." -- Phil Karlton
822+
823+
Once an URL is cached by a gateway cache, the cache will not ask the
824+
application for that content anymore. This allows the cache to provide fast
825+
responses and reduces the load on your application. However, you risk
826+
delivering outdated content. A way out of this dilemma is to use long
827+
cache lifetimes, but to actively notify the gateway cache when content
828+
changes. Reverse proxies usually provide a channel to receive such
829+
notifications, typically through special HTTP requests.
830+
831+
.. caution::
832+
833+
While cache invalidation is powerful, avoid it when possible. If you fail
834+
to invalidate something, outdated caches will be served for a potentially
835+
long time. Instead, use short cache lifetimes or use the validation model,
836+
and adjust your controllers to perform efficient validation checks as
837+
explained in :ref:`optimizing-cache-validation`.
838+
839+
Furthermore, since invalidation is a topic specific to each type of reverse
840+
proxy, using this concept will tie you to a specific reverse proxy or need
841+
additional efforts to support different proxies.
842+
843+
Sometimes, however, you need that extra performance you can get when
844+
explicitly invalidating. For invalidation, your application needs to detect
845+
when content changes and tell the cache to remove the URLs which contain
846+
that data from its cache.
847+
848+
.. tip::
849+
850+
If you want to use cache invalidation, have a look at the
851+
`FOSHttpCacheBundle`_. This bundle provides services to help with various
852+
cache invalidation concepts, and also documents the configuration for the
853+
a couple of common caching proxies.
854+
855+
If one content corresponds to one URL, the ``PURGE`` model works well.
856+
You send a request to the cache proxy with the HTTP method ``PURGE`` (using
857+
the word "PURGE" is a convention, technically this can be any string) instead
858+
of ``GET`` and make the cache proxy detect this and remove the data from the
859+
cache instead of going to Symfony to get a response.
860+
861+
Here is how you can configure the Symfony reverse proxy to support the
862+
``PURGE`` HTTP method::
863+
864+
// app/AppCache.php
865+
866+
// ...
867+
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
868+
use Symfony\Component\HttpFoundation\Request;
869+
use Symfony\Component\HttpFoundation\Response;
870+
871+
class AppCache extends HttpCache
872+
{
873+
protected function invalidate(Request $request, $catch = false)
874+
{
875+
if ('PURGE' !== $request->getMethod()) {
876+
return parent::invalidate($request, $catch);
877+
}
878+
879+
if ('127.0.0.1' !== $request->getClientIp()) {
880+
return new Response('Invalid HTTP method', Response::HTTP_BAD_REQUEST);
881+
}
882+
883+
$response = new Response();
884+
if ($this->getStore()->purge($request->getUri())) {
885+
$response->setStatusCode(200, 'Purged');
886+
} else {
887+
$response->setStatusCode(200, 'Not found');
888+
}
889+
890+
return $response;
891+
}
892+
}
893+
894+
.. caution::
895+
896+
You must protect the ``PURGE`` HTTP method somehow to avoid random people
897+
purging your cached data.
898+
899+
**Purge** instructs the cache to drop a resource in *all its variants*
900+
(according to the ``Vary`` header, see above). An alternative to purging is
901+
**refreshing** a content. Refreshing means that the caching proxy is
902+
instructed to discard its local cache and fetch the content again. This way,
903+
the new content is already available in the cache. The drawback of refreshing
904+
is that variants are not invalidated.
905+
906+
In many applications, the same content bit is used on various pages with
907+
different URLs. More flexible concepts exist for those cases:
908+
909+
* **Banning** invalidates responses matching regular expressions on the
910+
URL or other criteria;
911+
* **Cache tagging** lets you add a tag for each content used in a response
912+
so that you can invalidate all URLs containing a certain content.
913+
914+
.. index::
915+
single: Cache; ESI
916+
single: ESI
805917

806918
.. _edge-side-includes:
807919

@@ -1048,67 +1160,6 @@ The ``render_esi`` helper supports two other useful options:
10481160
of ``continue`` indicating that, in the event of a failure, the gateway cache
10491161
will simply remove the ESI tag silently.
10501162

1051-
.. index::
1052-
single: Cache; Invalidation
1053-
1054-
.. _http-cache-invalidation:
1055-
1056-
Cache Invalidation
1057-
------------------
1058-
1059-
"There are only two hard things in Computer Science: cache invalidation
1060-
and naming things." -- Phil Karlton
1061-
1062-
You should never need to invalidate cached data because invalidation is already
1063-
taken into account natively in the HTTP cache models. If you use validation,
1064-
you never need to invalidate anything by definition; and if you use expiration
1065-
and need to invalidate a resource, it means that you set the expires date
1066-
too far away in the future.
1067-
1068-
.. note::
1069-
1070-
Since invalidation is a topic specific to each type of reverse proxy,
1071-
if you don't worry about invalidation, you can switch between reverse
1072-
proxies without changing anything in your application code.
1073-
1074-
Actually, all reverse proxies provide ways to purge cached data, but you
1075-
should avoid them as much as possible. The most standard way is to purge the
1076-
cache for a given URL by requesting it with the special ``PURGE`` HTTP method.
1077-
1078-
Here is how you can configure the Symfony reverse proxy to support the
1079-
``PURGE`` HTTP method::
1080-
1081-
// app/AppCache.php
1082-
1083-
// ...
1084-
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
1085-
use Symfony\Component\HttpFoundation\Request;
1086-
use Symfony\Component\HttpFoundation\Response;
1087-
1088-
class AppCache extends HttpCache
1089-
{
1090-
protected function invalidate(Request $request, $catch = false)
1091-
{
1092-
if ('PURGE' !== $request->getMethod()) {
1093-
return parent::invalidate($request, $catch);
1094-
}
1095-
1096-
$response = new Response();
1097-
if ($this->getStore()->purge($request->getUri())) {
1098-
$response->setStatusCode(200, 'Purged');
1099-
} else {
1100-
$response->setStatusCode(404, 'Not purged');
1101-
}
1102-
1103-
return $response;
1104-
}
1105-
}
1106-
1107-
.. caution::
1108-
1109-
You must protect the ``PURGE`` HTTP method somehow to avoid random people
1110-
purging your cached data.
1111-
11121163
Summary
11131164
-------
11141165

@@ -1136,3 +1187,4 @@ Learn more from the Cookbook
11361187
.. _`P6 - Caching: Browser and intermediary caches`: http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache
11371188
.. _`FrameworkExtraBundle documentation`: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/cache.html
11381189
.. _`ESI`: http://www.w3.org/TR/esi-lang
1190+
.. _`FOSHttpCacheBundle`: http://foshttpcachebundle.readthedocs.org/

0 commit comments

Comments
 (0)