Invalidating old cache content on dynamic data in Symfony

Here’s just a quick note for those of you working with caching solutions for dynamic data in Symfony.

Update: If testability is a concern, please read the follow up to this article.

One of the challenges with caching is deciding where the limit is. What’s worth caching, and what isn’t. Because cleaning up that old data is hard… isn’t it?

Not so much!

You just need to make a helper and a checks, and you’ll be expertly picking out the templates to invalidate!

The first hurdle with clearing out invalid data, is that usually your backend is separate from the frontend, so it’s a non-trivial reach to try and invalidate cache files of other applications. Or is it?

<?php
 
class cacheAssistant
{
  public static function clearCachePattern($pattern)
  {
    $envs = array('prod', 'dev');
    $apps = array('backend', 'frontend');
    foreach($envs as $env)
    {
      foreach($apps as $app)
      {
        $app_cache_dir = sfConfig::get('sf_cache_dir').DIRECTORY_SEPARATOR.$app. DIRECTORY_SEPARATOR.$env.DIRECTORY_SEPARATOR.'template';
 	$cache_vars = array(
          'cache_dir' => $app_cache_dir,
   	  'cache_key_use_vary_headers' => true,
          'cache_key_use_host_name' => true,
        );
        $cache = new sfFileCache($cache_vars);
        $cache->removePattern($pattern);
      }
    }
  }
}

Your $cache_vars will differ depending on your cache settings, but essentially, that’s your main helper setup.

Now here’s what I use in my objects for cache clear detection:

<?php
 
class MyObject extends Doctrine_Record
{
  private $pendingClearCacheEntries = false;
  public function preSave($event)
  {
    if ($this->isModified())
      $this->pendingClearCacheEntries = true;
  }
  public function postSave($event)
  {
    if ($this->pendingClearCacheEntries)
    {
      $this->clearCacheEntries();
      $this->pendingClearCacheEntries = false;
    }
  }
  public function clearCacheEntries()
  {
    cacheAssistant::clearCachePattern('**/**/pages/index');
  }
}

Of course, your patterns will change depending on your cache options (I.e. I use the **/** because I have enabled cache_key_use_host_name, other settings may not accept this pattern.)

Happy caching, and if you have any questions, feel free to let me know!

One Comment

  1. Utpal

    libcanberra can do that for you just fine, just set the CA_PROP_MEDIA_FILENAME property when calilng ca_context_play().ca_context_play(ca_gtk_context_get(), 0, CA_PROP_MEDIA_FILENAME, path, NULL);If you need this from a shell use canberra-gtk-play which basically does this but a lot fancier.Note that while just passing the one filename is sufficient we encourage you to pass more properties, to easy a11y, yadda yadda.

    Reply

Leave a Reply to Utpal Cancel

*

twitter