Skip to content

Add support for kernel.cache_warmer #611

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
Xymanek opened this issue Nov 8, 2017 · 6 comments
Closed

Add support for kernel.cache_warmer #611

Xymanek opened this issue Nov 8, 2017 · 6 comments
Assignees
Milestone

Comments

@Xymanek
Copy link

Xymanek commented Nov 8, 2017

Version: latest (2.2.0)

Right now we have bin/console cache:warmup in our CD pipeline. Unfortunately, jms_serializer folder remains empty (unlike doctrine and twig). This causes performance hit on the first request that uses the serializer.

This is similar to #415 however this is about cache warmup instead of clearing

@pdugas
Copy link

pdugas commented Nov 15, 2017

This also means it cannot be used on platforms like Google App Engine's Standard PHP environment where writes to the local filesystem are not allowed. Would really like a warmup option for my Entity classes so I can use JMS Serializer.

@goetas
Copy link
Collaborator

goetas commented Nov 15, 2017 via email

@pdugas
Copy link

pdugas commented Nov 15, 2017

I did two things to make it work.

First, I commented out the is_dir() and is_writeable() checks in JMS' Metadata\Cache\FileCache constructor. Up on AppEngine, the is_writeable() return false. The check isn't necessary because of the next step.

Second, I created my own CacheWarmer to generate the cache files for my entities.

namespace AppBundle\CacheWarmer;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use JMS\Serializer\SerializerInterface;

class EntitySerializerCacheWarmer implements CacheWarmerInterface
{
    private $em;
    private $serializer;

    public function __construct(EntityManagerInterface $em, SerializerInterface $serializer)
    {
        $this->em = $em;
        $this->serializer = $serializer;
    }

    public function warmUp($cacheDir)
    {
        foreach ($this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames() as $class) {
            if (strpos($class, 'AppBundle\Entity') === 0) {
                $this->serializer->serialize(new $class(), 'json'); // result ignored
            }
        }
    }

    public function isOptional()
    {
        return true;
    }
}

Now I can cache:warmup and deploy. Working so far though only minimally tested.

@pdugas
Copy link

pdugas commented Nov 15, 2017

More generically, I think a way to list the classes that should be "warmed" makes sense. Maybe a way to specify classes in a namespace or just EM entities.

The strpos() check in my code was needed to prevent it from trying to serialize Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry which could not be instantiated because it's abstract. I'm planning on creating my own derivation of that baseclass so my API can expose logs.

@pdugas
Copy link

pdugas commented Nov 15, 2017

Oh, and making the list of classes to warm empty by default would make the addition of a custom CacheWarmer to the bundle backwards compatible.

@goetas goetas self-assigned this Nov 15, 2017
@goetas goetas added this to the v2.2 milestone Nov 15, 2017
@goetas
Copy link
Collaborator

goetas commented Nov 16, 2017

#615 is the WIP PR to solve the issue

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

No branches or pull requests

3 participants