diff --git a/apc.module b/apc.module index e29c9e0..ec41804 100644 --- a/apc.module +++ b/apc.module @@ -1,4 +1,39 @@ 'APC cache flush', + 'type' => MENU_CALLBACK, + 'page callback' => 'apc_drush_flush', + 'access callback' => TRUE, + ); + + return $items; +} + +/** + * Custom menu callback to enable clearing the cache from Drush/CLI. + */ +function apc_drush_flush() { + if (!isset($_GET['cron_key']) || variable_get('cron_key', 'drupal') != $_GET['cron_key']) { + watchdog('cron', 'APC could not flush cache(s) because an invalid key was used.', array(), WATCHDOG_NOTICE); + print t('APC could not flush cache(s) because an invalid key was used.'); + } + else { + foreach ($_GET['caches'] as $cache) { + list($bin, $cid, $wildcard) = explode('|', $cache); + + $apc = _cache_get_object($bin); + $apc->clear($cid, $wildcard == 1); + } + + print 'success'; // @todo: really? + } +} /** * Implementation of hook_init(). diff --git a/drupal_apc_cache.inc b/drupal_apc_cache.inc index 2f7e330..f48d8d0 100644 --- a/drupal_apc_cache.inc +++ b/drupal_apc_cache.inc @@ -38,6 +38,16 @@ class DrupalAPCCache implements DrupalCacheInterface { protected $prefix; /** + * @var array + */ + protected $drush_flush; + + /** + * @var boolean + */ + protected $drush; + + /** * Get prefix for bin using the configuration. * * @param string $bin @@ -75,6 +85,7 @@ class DrupalAPCCache implements DrupalCacheInterface { function __construct($bin) { $this->bin = $bin; + $this->drush = (drupal_is_cli() && function_exists('drush_log')); // First we determine the prefix from a setting. $prefix = self::getPrefixSettingForBin($this->bin); @@ -101,6 +112,31 @@ class DrupalAPCCache implements DrupalCacheInterface { $this->prefix = $prefix; } + function __destruct() { + if (!$this->drush) { + return; + } + + if (!empty($this->drush_flush) && isset($GLOBALS['conf']['apc_nodes']) && !empty($GLOBALS['conf']['apc_nodes'])) { + foreach ($GLOBALS['conf']['apc_nodes'] as $apc_node) { + $uri = url($apc_node . '/apc_drush_flush', array('query' => array( + 'caches' => $this->drush_flush, + 'cron_key' => variable_get('cron_key', 'drupal'), + ))); + $response = drupal_http_request($uri); + if ($response->code != 200) { + drush_log('APC could not flush cache(s) because ' . $apc_node . ' returned code ' . $response->code . ' (' . $response->error . ')', 'error'); + } + elseif ($response->data != 'success') { + drush_log($response->data, 'error'); + } + } + } + else { + drush_log('@todo', 'warning'); // @todo: add some sane errors + } + } + /** * Function which retrieves the safe key for the cache bin. * @@ -254,8 +290,8 @@ class DrupalAPCCache implements DrupalCacheInterface { } function clear($cid = NULL, $wildcard = FALSE) { - if (drupal_is_cli() && function_exists('drush_log')) { - drush_log($this->bin . '(' . $cid . ') was not cleared. APC cli uses a different memory storage then the webserver. For more info see: http://drupal.org/node/1278232', 'warning'); + if ($this->drush) { + $this->drush_flush[] = implode('|', array($this->bin, $cid, $wildcard)); return; }