Development

Changeset 7815

You must first sign up to be able to contribute.

Changeset 7815

Show
Ignore:
Timestamp:
03/12/08 02:03:48 (1 year ago)
Author:
fabien
Message:

rewrote the cache:clear task (closes #3072)

  • moved application and type argument to options (now you can remove all config cache for all applications)
  • added an env option to be able to remove the cache for only one environment
  • changed the way we find available applications (more robust)
  • caches are now cleaned by the cache objects defined in factories.yml (config, template, i18n, and routing)
  • cache:clear is now able to handle caches stored with any sfCache class
  • added a task.cache.clear event to be able to add new cache type, or override the cache cleaning process of an existing type (see sfSuperCachePlugin for an example)
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.1/lib/task/cache/sfCacheClearTask.class.php

    r7691 r7815  
    1919class sfCacheClearTask extends sfBaseTask 
    2020{ 
     21  protected 
     22    $config = null; 
     23 
    2124  /** 
    2225   * @see sfTask 
     
    2427  protected function configure() 
    2528  { 
    26     $this->addArguments(array( 
    27       new sfCommandArgument('application', sfCommandArgument::OPTIONAL, 'The application name'), 
    28       new sfCommandArgument('type', sfCommandArgument::OPTIONAL, 'The cache type to clear'), 
     29    $this->addOptions(array( 
     30      new sfCommandOption('app', null, sfCommandOption::PARAMETER_OPTIONAL, 'The application name', null), 
     31      new sfCommandOption('env', null, sfCommandOption::PARAMETER_OPTIONAL, 'The environment', null), 
     32      new sfCommandOption('type', null, sfCommandOption::PARAMETER_OPTIONAL, 'The type', 'all'), 
    2933    )); 
    3034 
     
    3741The [cache:clear|INFO] task clears the symfony cache. 
    3842 
    39 It removes all the files found in the [sf_cache_dir|COMMENT] directory 
    40 ([cache/|COMMENT] by default). It does not remove directories. 
    41  
    42 If it's called with an application name, it only clears the cache 
    43 for the given application. 
    44  
    45 For example, to clear the frontend application cache: 
    46  
    47   [./symfony cache:clear frontend|INFO] 
    48  
    49 If it's called with an application name and a type, it will only 
    50 clears the cache for the given application and type. 
    51 The symfony built-in types are: [config|COMMENT], [i18n|COMMENT] and [template|COMMENT]. 
    52  
    53 So, to clear the frontend application template cache: 
    54  
    55   [./symfony cache:clear frontend template|INFO] 
     43By default, it removes the cache for all available types, all applications, 
     44and all environments. 
     45 
     46You can restrict by type, application, or environment: 
     47 
     48For example, to clear the [frontend|COMMENT] application cache: 
     49 
     50  [./symfony cache:clear --app=frontend|INFO] 
     51 
     52To clear the cache for the [prod|COMMENT] environment for the [frontend|COMMENT] application: 
     53 
     54  [./symfony cache:clear --app=frontend --env=prod|INFO] 
     55 
     56To clear the cache for all [prod|COMMENT] environments: 
     57 
     58  [./symfony cache:clear --env=prod|INFO] 
     59 
     60To clear the [config|COMMENT] cache for all [prod|COMMENT] environments: 
     61 
     62  [./symfony cache:clear --type=config --env=prod|INFO] 
     63 
     64The built-in types are: [config|COMMENT], [i18n|COMMENT], [routing|COMMENT], and [template|COMMENT]. 
    5665 
    5766EOF; 
     
    6372  protected function execute($arguments = array(), $options = array()) 
    6473  { 
    65     $cacheDir = sfConfig::get('sf_cache_dir'); 
    66     if (!$cacheDir || !is_dir($cacheDir)) 
    67     { 
    68       throw new sfException(sprintf('Cache directory "%s" does not exist.', $cacheDir)); 
    69     } 
    70  
    71     // app 
    72     $mainApp = ''; 
    73     if (isset($arguments['application'])) 
    74     { 
    75       $mainApp = $arguments['application']; 
    76     } 
    77  
    78     // type (template, i18n or config) 
    79     $mainType = ''; 
    80     if (isset($arguments['type'])) 
    81     { 
    82       $mainType = $arguments['type']; 
    83     } 
    84  
    85     // declare type that must be cleaned safely (with a lock file during cleaning) 
    86     $safeTypes = array('config', 'i18n'); 
    87  
    88     // finder to remove all files in a cache directory 
    89     $finder = sfFinder::type('file')->ignore_version_control()->discard('.sf'); 
     74    if (!sfConfig::get('sf_cache_dir') || !is_dir(sfConfig::get('sf_cache_dir'))) 
     75    { 
     76      throw new sfException(sprintf('Cache directory "%s" does not exist.', sfConfig::get('sf_cache_dir'))); 
     77    } 
    9078 
    9179    // finder to find directories (1 level) in a directory 
     
    9381 
    9482    // clear global cache 
    95     if (!$mainApp
    96     { 
    97       $this->getFilesystem()->remove($finder->in(sfConfig::get('sf_cache_dir'))); 
     83    if (is_null($options['app'])
     84    { 
     85      $this->getFilesystem()->remove(sfFinder::type('file')->ignore_version_control()->discard('.sf')->in(sfConfig::get('sf_cache_dir'))); 
    9886    } 
    9987 
    10088    // iterate through applications 
    101     $apps = array(); 
    102     if ($mainApp) 
    103     { 
    104       $apps[] = $mainApp; 
    105     } 
    106     else 
    107     { 
    108       $apps = $dirFinder->in($cacheDir); 
    109     } 
    110  
     89    $apps = is_null($options['app']) ? $dirFinder->in(sfConfig::get('sf_apps_dir')) : array($options['app']); 
    11190    foreach ($apps as $app) 
    11291    { 
    113       if (!is_dir($cacheDir.'/'.$app)) 
     92      if (!is_dir(sfConfig::get('sf_cache_dir').'/'.$app)) 
    11493      { 
    11594        continue; 
    11695      } 
    11796 
    118       // remove cache for all environments 
    119       foreach ($dirFinder->in($cacheDir.'/'.$app) as $env) 
     97      $class = $app.'Configuration'; 
     98      require_once sfConfig::get('sf_lib_dir').'/'.$class.'.class.php'; 
     99      $appConfiguration = new $class('dev', true); 
     100 
     101      // iterate through environments 
     102      $envs = is_null($options['env']) ? $dirFinder->in(sfConfig::get('sf_cache_dir').'/'.$app) : array($options['env']); 
     103      foreach ($envs as $env) 
    120104      { 
    121         // which types? 
    122         $types = array(); 
    123         if ($mainType) 
     105        if (!is_dir(sfConfig::get('sf_cache_dir').'/'.$app.'/'.$env)) 
    124106        { 
    125           $types[] = $mainType; 
     107          continue; 
    126108        } 
    127         else 
     109 
     110        $this->logSection('cache', sprintf('Clearing cache type "%s" for "%s" app and "%s" env', $options['type'], $app, $env)); 
     111 
     112        $this->lock($app, $env); 
     113 
     114        $event = $appConfiguration->getEventDispatcher()->notifyUntil(new sfEvent($this, 'task.cache.clear', array('app' => $appConfiguration, 'env' => $env, 'type' => $options['type']))); 
     115        if (!$event->isProcessed()) 
    128116        { 
    129           $types = $dirFinder->in($cacheDir.'/'.$app.'/'.$env); 
     117          // default cleaning process 
     118          $method = $this->getClearCacheMethod($options['type']); 
     119          if (!method_exists($this, $method)) 
     120          { 
     121            throw new InvalidArgumentException(sprintf('Don\'t know how to remove the cache for type "%s".', $options['type'])); 
     122          } 
     123          $this->$method($appConfiguration, $env); 
    130124        } 
    131125 
    132         foreach ($types as $type) 
    133         { 
    134           $subDir = $cacheDir.'/'.$app.'/'.$env.'/'.$type; 
    135  
    136           if (!is_dir($subDir)) 
    137           { 
    138             continue; 
    139           } 
    140  
    141           // remove cache files 
    142           if (in_array($type, $safeTypes)) 
    143           { 
    144             $this->safeCacheRemove($finder, $subDir, $app.'_'.$env); 
    145           } 
    146           else 
    147           { 
    148             $this->getFilesystem()->remove($finder->in(sfConfig::get('sf_root_dir').'/'.$subDir)); 
    149           } 
    150         } 
     126        $this->unlock($app, $env); 
    151127      } 
    152128    } 
    153129  } 
    154130 
    155   /** 
    156    * Removes a directory safely. 
    157    * 
    158    * @param object $finder 
    159    * @param string $subDir 
    160    * @param string $lockName 
    161    */ 
    162   protected function safeCacheRemove($finder, $subDir, $lockName) 
     131  protected function getClearCacheMethod($type) 
     132  { 
     133    return sprintf('clear%sCache', ucfirst($type)); 
     134  } 
     135 
     136  protected function clearAllCache(sfApplicationConfiguration $appConfiguration, $env) 
     137  { 
     138    $this->clearI18NCache($appConfiguration, $env); 
     139    $this->clearRoutingCache($appConfiguration, $env); 
     140    $this->clearTemplateCache($appConfiguration, $env); 
     141    $this->clearConfigCache($appConfiguration, $env); 
     142  } 
     143 
     144  protected function clearConfigCache(sfApplicationConfiguration $appConfiguration, $env) 
     145  { 
     146    $subDir = sfConfig::get('sf_cache_dir').'/'.$appConfiguration->getApplication().'/'.$env.'/config'; 
     147    if (is_dir($subDir)) 
     148    { 
     149      // remove cache files 
     150      $this->getFilesystem()->remove(sfFinder::type('file')->ignore_version_control()->discard('.sf')->in($subDir)); 
     151    } 
     152  } 
     153 
     154  protected function clearI18NCache(sfApplicationConfiguration $appConfiguration, $env) 
     155  { 
     156    $config = $this->getFactoriesConfiguration($appConfiguration); 
     157 
     158    $this->cleanCacheFromFactoryConfig($config['i18n']['param']['cache']['class'], $config['i18n']['param']['cache']['param']); 
     159  } 
     160 
     161  protected function clearRoutingCache(sfApplicationConfiguration $appConfiguration, $env) 
     162  { 
     163    $config = $this->getFactoriesConfiguration($appConfiguration); 
     164 
     165    $this->cleanCacheFromFactoryConfig($config['routing']['param']['cache']['class'], $config['routing']['param']['cache']['param']); 
     166  } 
     167 
     168  protected function clearTemplateCache(sfApplicationConfiguration $appConfiguration, $env) 
     169  { 
     170    $config = $this->getFactoriesConfiguration($appConfiguration); 
     171 
     172    $this->cleanCacheFromFactoryConfig($config['view_cache']['class'], $config['view_cache']['param']); 
     173  } 
     174 
     175  public function getFactoriesConfiguration(sfApplicationConfiguration $appConfiguration) 
     176  { 
     177    if (is_null($this->config)) 
     178    { 
     179      $this->config = sfFactoryConfigHandler::getConfiguration($appConfiguration->getConfigPaths('config/factories.yml')); 
     180    } 
     181 
     182    return $this->config; 
     183  } 
     184 
     185  public function cleanCacheFromFactoryConfig($class, $parameters = array()) 
     186  { 
     187    $cache = new $class($parameters); 
     188    $cache->clean(); 
     189  } 
     190 
     191  protected function lock($app, $env) 
    163192  { 
    164193    // create a lock file 
    165     $this->getFilesystem()->touch(sfConfig::get('sf_cache_dir').'/'.$lockName.'.lck'); 
     194    $this->getFilesystem()->touch($this->getLockFile($app, $env)); 
    166195 
    167196    // change mode so the web user can remove it if we die 
    168     $this->getFilesystem()->chmod(sfConfig::get('sf_cache_dir').'/'.$lockName.'.lck', 0777); 
    169  
    170     // remove cache files 
    171     $this->getFilesystem()->remove($finder->in(sfConfig::get('sf_root_dir').'/'.$subDir)); 
    172  
     197    $this->getFilesystem()->chmod($this->getLockFile($app, $env), 0777); 
     198  } 
     199 
     200  protected function unlock($app, $env) 
     201  { 
    173202    // release lock 
    174     $this->getFilesystem()->remove(sfConfig::get('sf_cache_dir').'/'.$lockName.'.lck'); 
     203    $this->getFilesystem()->remove($this->getLockFile($app, $env)); 
     204  } 
     205 
     206  protected function getLockFile($app, $env) 
     207  { 
     208    return sfConfig::get('sf_cache_dir').'/'.$app.'_'.$env.'.lck'; 
    175209  } 
    176210} 

The Sensio Labs Network

Since 1998, Sensio Labs has been promoting the Open-Source software movement by providing quality web application development, training, consulting, and supporting several large Open-Source projects.