Skip to content

Documentation for the new PSR-6 Cache component #6171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 of 2 tasks
xabbuh opened this issue Jan 20, 2016 · 23 comments
Closed
1 of 2 tasks

Documentation for the new PSR-6 Cache component #6171

xabbuh opened this issue Jan 20, 2016 · 23 comments

Comments

@xabbuh
Copy link
Member

xabbuh commented Jan 20, 2016

@xabbuh xabbuh added the Cache label Jan 20, 2016
@xabbuh xabbuh added this to the 3.1 milestone Jan 20, 2016
@javiereguiluz
Copy link
Member

I love the energy and passion that the Symfony community is showing around the new Cache component. I'd like to start documenting it and adding it to symfony.com list of components.


But before that, I'd like to share with you how I'd like this new cache to work in Symfony. I'd like to have a "global" and standard way of using a cache for services and bundles. Similar to the way we use Monolog today for logging anything.

So, my question: is the following explanation how the Cache would work in Symfony?


Defining application caches

When defining one cache, Symfony names it default automatically (same behavior as "swiftmailer" mailers and "doctrine" managers)

# app/config/config.yml

# simple cache without arguments
cache:
    type: array

# equivalent to:
# cache:
#    default:
#        type: array

Complex caches can define arguments:

# app/config/config.yml
cache:
    type: doctrine
    em: my_custom_em_id

You can also define lots of different caches in a single app:

# app/config/config.yml
cache:
    default:
        type: array
    db:
        type: doctrine
        em: my_custom_em_id

They are available in the application as cache.default and cache.db services.
The cache service is an alias for cache.default.

Configuring the application caches

Params such as default_lifetime and namespace are available for any cache type:

# app/config/config.yml
cache:
    type: array
    default_lifetime: 600
    namespace: 'ACME__'

Using caches in Symfony components

All Symfony components define a cache option. Its value can be:

  1. A boolean, to enable or disable the cache. If true, the default cache is used:
# app/config/config.yml
framework:
    validation:
        cache: true
        enable_annotations: true
    serializer:
        cache: true
    property_path:
        cache: true

doctrine:
    orm:
        cache: true
# you can also set 'metadata_cache_driver', 'result_cache_driver' 
# and 'query_cache_driver' separately

You can also set the id of the cache and even an array of cache ids for complex services:

# app/config/config.yml
framework:
    validation:
        cache: db
        enable_annotations: true
    serializer:
        cache: default
    property_path:
        cache: default

doctrine:
    orm:
        cache: [db, default]

This cache can also be used for third-party bundles:

# app/config/config.yml
liip_imagine:
    cache: true # or false, or 'db', or ['db', 'default'], etc.

@wouterj
Copy link
Member

wouterj commented Jan 20, 2016

What you are mentioning is not Component docs, but bundle docs (cookbook related), @javiereguiluz.

Apart from that, I cannot answer your questions as I haven't looked at caching yet

@xabbuh
Copy link
Member Author

xabbuh commented Jan 25, 2016

@javiereguiluz Your ideas sound quite nice to me and I think you should raise this idea in the code repo (we are not there right now, but the work to integrate PSR-6 caches in the different components has started). Some of the things you talk about are out of the scope of the Symfony core as they need to be handled in third-party bundles, but we should of course think about how can make using the new cache component as easy as possible.

@xabbuh
Copy link
Member Author

xabbuh commented Jan 26, 2016

For anyone interested: Javier opened symfony/symfony#17537.

@teohhanhui
Copy link
Contributor

teohhanhui commented Apr 22, 2016

Is there any documentation for symfony/symfony#18371 (also symfony/symfony#18544 and symfony/symfony#18561 which introduced default cache pools for the Validator and Serializer)?

@nicolas-grekas @tgalopin

How would the user switch to use ApcuAdapter, for instance? Is it by overriding the adapter for the default cache pools, or by declaring new cache pools?

The recommended (as per config_prod.yml in symfony-standard) validator.mapping.cache.doctrine.apc and serializer.mapping.cache.doctrine.apc are using the old ApcCache which requires the apcu_bc PECL package (apc.so extension) for PHP >= 7. I think that needs to change...

@tgalopin
Copy link
Contributor

tgalopin commented Apr 22, 2016

@teohhanhui You are right, these PR should be documented.

However, note that these three PR do not change any behavior when the user enabled APC cache: these PR are simply a fallback to filesystem when the user didn't change the config_prod file.

The recommended cache will also need to change from APC to OPCache as much as possible. That's the aim of the PR symfony/symfony#18533 and there will be other PRs for other components (validator and serializer mainly).

PS : the cache pools system definitely needs some documentation, it's a really powerful system but more complex than what was present before.

@tgalopin
Copy link
Contributor

This comment could be a good basis for documentation: symfony/symfony#18371 (comment)

@teohhanhui
Copy link
Contributor

teohhanhui commented Apr 22, 2016

@teohhanhui
Copy link
Contributor

teohhanhui commented Apr 22, 2016

If so, then shouldn't that be the new recommendation in config_prod.yml?

p/s: OpCacheAdapter or ApcuAdapter, that's a separate issue...

@tgalopin
Copy link
Contributor

@teohhanhui Your configuration sample is right, but as it's not completely stable yet (some ideas emerged to improve developer experience on various levels), it's not yet documented. But it should be before release, that's true.

@javiereguiluz
Copy link
Member

I'm trying to write the docs for this component (and its integration with FrameworkBundle). So I'll ask for help to @tgalopin and @nicolas-grekas to see if I understand their work.


In the Symfony Demo app, we have this action to display the blog index:

    public function indexAction($page)
    {
        $posts = $this->get('cache.pool.local')->getItem('blog-posts-latest');

        return $this->render('blog/index.html.twig', array('posts' => $posts));
    }

I'm trying to use a filesystem cache to avoid the database query:

    public function indexAction($page)
    {
        if ($this->get('cache.pool.local')->hasItem('blog-posts-latest')) {
            $posts = $this->get('cache.pool.local')->getItem('blog-posts-latest');
        } else {
            $posts = $this->getDoctrine()->getRepository('AppBundle:Post')->findLatest($page);
            $item = $this->get('cache.pool.local')->getItem('blog-posts-latest');
            $item->set($posts);
            $this->get('cache.pool.local')->save($item);
        }

        return $this->render('blog/index.html.twig', array('posts' => $posts));
    }

The "pools" are created, but no contents are cached. Everything is empty:

cache_pools

Any clue? Thanks!

@teohhanhui
Copy link
Contributor

teohhanhui commented Apr 25, 2016

You should call Psr\Cache\CacheItemInterface::isHit. Also, note that Psr\Cache\CacheItemPoolInterface::getItem returns Psr\Cache\CacheItemInterface, so the following is obviously wrong:

// wrong!
$posts = $this->get('cache.pool.local')->getItem('blog-posts-latest');

It's unsafe to use the - character in cache key as it's not guaranteed to be supported.

Working example: https://github.com/api-platform/core/blob/b655b91f83e2acb4040767dab51452512638e45c/src/Metadata/Property/Factory/CachedPropertyMetadataFactory.php

@javiereguiluz
Copy link
Member

@teohhanhui I've changed the code like this, but everything is still empty:

    public function indexAction($page)
    {
        $cachedPosts = $this->get('cache.pool.local')->getItem('blog-posts-latest');

        if ($cachedPosts->isHit()) {
            $posts = $cachedPosts->get();
        } else {
            $posts = $this->getDoctrine()->getRepository('AppBundle:Post')->findLatest($page);
            $cachedPosts->set($posts);
            $this->get('cache.pool.local')->save($cachedPosts);
        }

        return $this->render('blog/index.html.twig', array('posts' => $posts));
    }

@javiereguiluz
Copy link
Member

@teohhanhui OK, the problem was that I was trying to cache a Pagerfanta object and somehow that cannot be cached. Sadly I didn't get any exception or error message or log. If I cache $posts->getIterator(), it works.

@nicolas-grekas
Copy link
Member

@javiereguiluz PSR-6 forbids throwing exceptions for unserializable values. But we could easily add a logger, only a service tag is missing. In which channel would you do that?

@javiereguiluz
Copy link
Member

What about using cache as the channel?

@nicolas-grekas
Copy link
Member

See symfony/symfony#18631

@wouterj wouterj added the hasPR A Pull Request has already been submitted for this issue. label May 21, 2016
@teohhanhui
Copy link
Contributor

Need to document symfony/symfony#18667

@javiereguiluz
Copy link
Member

@teohhanhui yes, but I'll do that in a separate PR. This is only for the component and then we'll document the integration of Cache in the Symfony framework.

@xabbuh xabbuh closed this as completed in 3b80d27 Jun 30, 2016
@Arkemlar
Copy link

@javiereguiluz I am confused, where can I find complete description of cache component configuration in symfony framework? There is nothing about it in symfony docs website.

@javiereguiluz
Copy link
Member

@Arkemlar sadly that's correct! We don't have yet this doc about using Cache inside the Symfony framework.

@HeahDude HeahDude removed the hasPR A Pull Request has already been submitted for this issue. label Mar 26, 2017
@HeahDude
Copy link
Contributor

Reopening, the framework integration is indeed still missing as stated in the original post.

@HeahDude HeahDude reopened this Mar 26, 2017
@HeahDude HeahDude modified the milestones: 3.2, 3.1 Apr 15, 2017
@HeahDude
Copy link
Contributor

HeahDude commented Apr 15, 2017

Closing again as we already track it in #7006.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants