Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Completed the chapter about cache pools
  • Loading branch information
javiereguiluz committed Apr 26, 2016
commit 2d712220af717c2086397ae0d3396aabef5275f7
152 changes: 149 additions & 3 deletions components/cache/cache_pools.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
.. index::
single: Cache Pool
single: APC Cache, APCu Cache
single: Doctrine Cache
single: Redis Cache

Cache Pools
===========
Expand All @@ -13,10 +16,151 @@ changes from a filesystem based cache to a Redis or database based cache.
Creating Cache Pools
--------------------

Cache Pools are classes which implement the :class:`Psr\\Cache\\CacheItemPoolInterface`
interface.
Cache Pools are created through the **cache adapters**, which are classes that
implement the :class:`Psr\\Cache\\CacheItemPoolInterface` interface. This
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"which" refers to "cache adapters", these implement AdapterInterface (which extends CacheItemPoolInterface).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this comment. Please tell me how to reword this paragraph:

Cache Pools are created through the **cache adapters**, which are classes that implement the :class:`Psr\\Cache\\CacheItemPoolInterface` interface. This component provides several adapters ready to use in your applications. 

Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the current situation, it seems like I need to implement CacheItemPoolInterface when I want to create a custom adapter. However, I have to to implement AdapterInterface (unless I'm wrong of course).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true for symfony derivated adapters (AdapterInterface extends CacheItemPoolInterface)

component provides several adapters ready to use in your applications.

.. TODO: how do you create Cache Pools?
Array Cache Adapter
~~~~~~~~~~~~~~~~~~~

This adapter is only useful for testing purposes because contents are stored in
memory and no persisted in any way. Besides, some features explained later are
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not persisted

not available, such as the deferred saves::

use Symfony\Component\Cache\Adapter\ArrayAdapter;

$cache = new ArrayAdapter($defaultLifetime = 0, $storeSerialized = true);

``defaultLifetime``
**type**: integer, **default value**: ``0``
The default lifetime, in seconds, applied to cache items that don't define
their own lifetime. The default value (``0``) means an "infinite" lifetime,
but this adapter destroys the cache once the current PHP execution finishes.

``storeSerialized``
**type**: boolean, **default value**: ``true``
If ``true``, the values saved in the cache are serialized before storing them.

Filesystem Cache Adapter
~~~~~~~~~~~~~~~~~~~~~~~~

This adapter is useful when you want to improve the application performance but
can't install in the server tools like APC or Redis::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It stores cached items in a set of directories on the local file system.


use Symfony\Component\Cache\Adapter\FilesystemAdapter;

$cache = new FilesystemAdapter($namespace = '', $defaultLifetime = 0, $directory = null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$pool?


``namespace``
**type**: string, **default value**: ``''`` (an empty string)
The subdirectory created inside the main cache directory (defined in the
third argument) to store the cache items.

``defaultLifetime``
**type**: integer, **default value**: ``0``
The default lifetime, in seconds, applied to cache items that don't define
their own lifetime. The default value (``0``) means an "infinite" lifetime,
which this adapter respects because items are actually persisted.

``directory``
**type**: string, **default value**: ``null``
The directory where the cache items are stored as files. Make sure that this
directory has read-write permissions for your application. If no directory
is defined, a new directory called ``symfony-cache/`` is created in the
system's temporary directory.

APCu Cache Adapter
~~~~~~~~~~~~~~~~~~

This adapter can increase the application performance very significantly, because
contents are cached in the memory of your server, which is much faster than the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the shared memory

filesystem. It requires to have installed and enabled the PHP APC extension::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that APCu should be recommended for mostly-append populating scenarios. Having lots of delete&writes creates fragmentation which can degrade performance significantly.


use Symfony\Component\Cache\Adapter\ApcuAdapter;

$cache = new ApcuAdapter($namespace = '', $defaultLifetime = 0);

``namespace``
**type**: string, **default value**: ``''`` (an empty string)
The string prefixed to the keys of the items stored in this cache.

``defaultLifetime``
**type**: integer, **default value**: ``0``
The default lifetime, in seconds, applied to cache items that don't define
their own lifetime. The default value (``0``) means an "infinite" lifetime,
which in this adapter ends when the web server is restarted or the APC memory
is deleted in any other way.

Redis Cache Adapter
~~~~~~~~~~~~~~~~~~~

This adapter, similarly to APCu adapter, can increase the application performance
very significantly, because contents are cached in the memory of your server. It
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description makes it as if Redis is like APCu (both store content "in the memory of your server").
But of course the difference is much more than that: Redis is accessed through network protocols, which means cached items can be shared by several PHP fronts, whearas APCu is accessed through shared memory, which is local to one single PHP server.

requires to have installed Redis and have created a connection that implements
``\Redis`` class::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the Redis


use Symfony\Component\Cache\Adapter\RedisAdapter;

$cache = new RedisAdapter(\Redis $redisConnection, $namespace = '', $defaultLifetime = 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$pool?


``redisConnection``
**type**: ``\Redis``, **default value**: (none, this argument is mandatory)
The object that represents a valid connection to your Redis system.

``namespace``
**type**: string, **default value**: ``''`` (an empty string)
The string prefixed to the keys of the items stored in this cache.

``defaultLifetime``
**type**: integer, **default value**: ``0``
The default lifetime, in seconds, applied to cache items that don't define
their own lifetime. The default value (``0``) means an "infinite" lifetime,
which in this adapter ends when the server is restarted or the Redis memory
is deleted in any other way.

Chain Cache Adapter
~~~~~~~~~~~~~~~~~~~

This adapter allows to combine any number of the previous adapters. Cache items
are fetched from the first adapter which contains them. Besides, cache items are
saved in all the given adapters, so this is a quick way of creating a cache
replication::

use Symfony\Component\Cache\Adapter\ApcuAdapter;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;

$apcCache = new ApcuAdapter();
$fileCache = new FilesystemAdapter();

$cache = new ChainAdapter(array($apcCache, $fileCache));

The second optional argument of ``ChainAdapter`` is the ``maxLifetime`` (default
``0``) which is the maximum lifetime of items propagated from lower adapters to
upper ones.

.. TODO: I don't understand the previous phrase, which is copied from the ChainAdapter code.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when an item is not found in the first pool but is found in the second, the ChainAdapter ensures that the just fetched item is saved in the first pool where it were missing. But with which lifetime? Since there is no way to know of much time the item will remain in the second adapter where it were found, we need a default value, here comes $maxLifetime

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment. I understand this now.

However, I don't understand why we need this. If an item is found in the second pool, we now when expires it. Why cannot we create the item in the first pool and set its expiration with expiresAt() ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do not know when it expires, that's exactly the point

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can't you know when an existing item expires?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can you know when an existing item expires? :)


Proxy Cache Adapter
~~~~~~~~~~~~~~~~~~~

.. TODO: what is this adapter useful for?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two use cases: PSR-6 interop of cache items implementations. Without it, you can't fetch a cache item from a non-symfony pool and save it in a Symfony one. The second use case if getting stats about hits/misses in the current script context (see getHits/getMisses functions).


Doctrine Cache Adapter
~~~~~~~~~~~~~~~~~~~~~~

This adapter wraps any `Doctrine Cache`_ provider so you can use them in your
application as if they were Symfony Cache adapters::

use Doctrine\Common\Cache\SQLite3Cache;
use Symfony\Component\Cache\Adapter\DoctrineAdapter;

$doctrineCache = new SQLite3(__DIR__.'/cache/data.sqlite');
$symfonyCache = new DoctrineAdapter($doctrineCache);

This adapter also defines two optional arguments called ``namespace`` (default:
``''``) and ``defaultLifetime`` (default: ``0``) and adapts them to make them
work in the underlying Doctrine cache.

Looking for Cache Items
-----------------------
Expand Down Expand Up @@ -102,3 +246,5 @@ method (which returns ``true`` when all items are successfully deleted)::

// ...
$cacheIsEmpty = $cache->clear();

.. _`Doctrine Cache`: https://github.com/doctrine/cache
5 changes: 2 additions & 3 deletions components/cache/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,11 @@ Basic Usage
This component is a strict implementation of `PSR-6`_, which means that the API
is the same as defined in the standard. Before starting to cache information,
create the cache pool using any of the built-in adapters. For example, to create
a filesystem-based cache, instantiate :class:`Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter`
and define the namespace used to store the items as the first argument::
a filesystem-based cache, instantiate :class:`Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter`::

use Symfony\Component\Cache\Adapter\FilesystemAdapter;

$cache = new FilesystemAdapter('app.cache')
$cache = new FilesystemAdapter();

Now you can create, retrieve, updated and delete items using this cache pool::

Expand Down