Changeset 982
- Timestamp:
- 04/02/09 12:46:50 (14 years ago)
- Location:
- plugins/memCache
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
plugins/memCache/README
r186 r982 6 6 You may add the following constants in your main config.php file: 7 7 8 DC_MC_CACHE_ENABLE : set to false to disable caching system (default true) 9 DC_MC_CACHE_HOST : hostname of the server hosting the memcached instance (default localhost) 10 DC_MC_CACHE_PORT : port of the memcached instance (default 11211) 8 DC_MC_CACHE_ENABLE : set to false to disable caching system (default true) 9 DC_MC_CACHE_HOST : hostname of the server hosting the memcached instance (default localhost) 10 DC_MC_CACHE_PORT : port of the memcached instance (default 11211) 11 DC_MC_CACHE_PERSISTENT : establish a persistent connection to memcached 12 DC_MC_CACHE_SCHEDULED : ensure posts scheduling compatibiliy 13 14 15 HINTS 16 ----- 17 18 If you want cache to be called before *any* connection to database, add a 19 require statement to _post_config.php at the end of your configuration file. -
plugins/memCache/_define.php
r217 r982 2 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 3 # 4 # This file is part of Dotclear 2.4 # This file is part of MemCache, a plugin for Dotclear 2. 5 5 # 6 # Copyright (c) 200 3-2008 Olivier Meunierand contributors6 # Copyright (c) 2008-2009 Alain Vagner, Pep and contributors 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 10 10 # 11 11 # -- END LICENSE BLOCK ------------------------------------ 12 if (!defined('DC_RC_PATH')) { return; } 12 13 13 14 $this->registerModule( 14 15 /* Name */ "MemCache", 15 16 /* Description*/ "Blog pages cache using memcached", 16 /* Author */ " Olivier Meunierand contributors",17 /* Version */ ' 0.1',17 /* Author */ "Alain Vagner, Pep and contributors", 18 /* Version */ '1.0-beta2', 18 19 /* Permissions */ null 19 20 ); -
plugins/memCache/_prepend.php
r217 r982 2 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 3 # 4 # This file is part of Dotclear 2.4 # This file is part of MemCache, a plugin for Dotclear 2. 5 5 # 6 # Copyright (c) 200 3-2008 Olivier Meunierand contributors6 # Copyright (c) 2008-2009 Alain Vagner, Pep and contributors 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 10 10 # 11 11 # -- END LICENSE BLOCK ------------------------------------ 12 if (!defined('DC_RC_PATH')) { return; } 12 13 13 14 if (!defined('DC_MC_CACHE_ENABLE')) { 14 define('DC_MC_CACHE_ENABLE', true);15 define('DC_MC_CACHE_ENABLE',class_exists('Memcache')); 15 16 } 16 17 … … 23 24 } 24 25 25 26 if (!DC_MC_CACHE_ENABLE) { 27 return; 26 if (!defined('DC_MC_CACHE_PERSISTENT')) { 27 define('DC_MC_CACHE_PERSISTENT', false); 28 28 } 29 29 30 # We need touch function 31 if (!class_exists('Memcache')) { 32 return; 30 if (!defined('DC_MC_CACHE_SCHEDULED')) { 31 define('DC_MC_CACHE_SCHEDULED',false); 33 32 } 33 34 if (!DC_MC_CACHE_ENABLE) return; 34 35 35 36 $GLOBALS['__autoload']['dcMemCache'] = dirname(__FILE__).'/class.cache.php'; 36 37 37 $core->addBehavior('urlHandlerServeDocument',array('dcMemCacheBehaviors','urlHandlerServeDocument')); 38 $core->addBehavior('publicBeforeDocument',array('dcMemCacheBehaviors','publicBeforeDocument')); 38 $core->addBehavior('urlHandlerServeDocument', array('dcMemCacheBehaviors','urlHandlerServeDocument')); 39 $core->addBehavior('publicBeforeDocument', array('dcMemCacheBehaviors','publicBeforeDocument')); 40 $core->addBehavior('coreBlogAfterTriggerBlog', array('dcMemCacheBehaviors','coreBlogAfterTriggerBlog')); 39 41 40 42 class dcMemCacheBehaviors … … 44 46 try 45 47 { 46 $cache = new dcMemCache( DC_MC_CACHE_HOST, DC_MC_CACHE_PORT);48 $cache = new dcMemCache($_SERVER['REQUEST_URI'],DC_MC_CACHE_HOST,DC_MC_CACHE_PORT,DC_MC_CACHE_PERSISTENT); 47 49 48 50 $do_cache = true; 49 51 50 52 # We have POST data, no cache 51 if (!empty($_POST)) { 52 $do_cache = false; 53 } 53 if (!empty($_POST)) $do_cache = false; 54 54 55 55 # This is a post with a password, no cache … … 58 58 } 59 59 60 if ($do_cache) 61 { 60 if ($do_cache) { 62 61 # No POST data or COOKIE, do cache 63 $cache->storePage($ _SERVER['REQUEST_URI'],$result['content_type'],$result['content'],$result['blogupddt']);62 $cache->storePage($result['content_type'],$result['content'],$result['blogupddt']); 64 63 } 65 else 66 { 64 else { 67 65 # Remove cache file 68 $cache->dropPage( $_SERVER['REQUEST_URI']);66 $cache->dropPage(); 69 67 } 70 68 } … … 74 72 public static function publicBeforeDocument(&$core) 75 73 { 76 if (!empty($_POST)) { 77 return; 78 } 74 if (!empty($_POST)) return; 79 75 80 try 81 { 82 $cache = new dcMemCache(DC_MC_CACHE_HOST, DC_MC_CACHE_PORT); 83 $ts = $cache->getPageMTime($_SERVER['REQUEST_URI']); 76 try { 77 $cache = new dcMemCache($_SERVER['REQUEST_URI'],DC_MC_CACHE_HOST,DC_MC_CACHE_PORT,DC_MC_CACHE_PERSISTENT); 78 $ts = $cache->getPageMTime(); 84 79 85 if ($ts !== false) 86 { 87 $mod_ts = array_merge(array($ts), $GLOBALS['mod_ts']); 88 self::cache($mod_ts); 89 if ($cache->fetchPage($_SERVER['REQUEST_URI'],$GLOBALS['core']->blog->upddt)) { 80 if ($ts !== false) { 81 if (DC_MC_CACHE_SCHEDULED) { 82 if ($core->blog->url == http::getSelfURI()) { 83 $core->blog->publishScheduledEntries(); 84 } 85 } 86 $blog_ts = $GLOBALS['core']->blog->upddt; 87 dcMemCache::httpCache(array($ts,$blog_ts)); 88 if ($cache->fetchPage($blog_ts)) { 90 89 exit; 91 90 } … … 95 94 } 96 95 97 public static function cache($mod_ts=array()) 98 { 99 rsort($mod_ts); 100 $ts = $mod_ts[0]; 96 public static function coreBlogAfterTriggerBlog($cur) 97 { 98 global $core; 101 99 102 $since = NULL; 103 if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { 104 $since = $_SERVER['HTTP_IF_MODIFIED_SINCE']; 105 $since = preg_replace ('/^(.*)(Mon|Tue|Wed|Thu|Fri|Sat|Sun)(.*)(GMT)(.*)/', '$2$3 GMT', $since); 106 $since = strtotime($since); 100 try { 101 $cache = new dcMemCache(null,DC_MC_CACHE_HOST,DC_MC_CACHE_PORT,DC_MC_CACHE_PERSISTENT); 102 $host = preg_replace('#^(http://(?:.+?))/(.*)$#','$1',$core->blog->url); 103 $cache->setBlogMTime($host,$core->blog->id); 107 104 } 108 109 # Common headers list 110 $headers[] = 'Last-Modified: '.gmdate('D, d M Y H:i:s',$ts).' GMT'; 111 $headers[] = 'Cache-Control: must-revalidate, max-age=0'; 112 $headers[] = 'Pragma:'; 113 114 if ($since >= $ts) 115 { 116 http::head(304,'Not Modified'); 117 foreach ($headers as $v) { 118 header($v); 119 } 120 exit; 121 } 122 else 123 { 124 header('Date: '.gmdate('D, d M Y H:i:s').' GMT'); 125 foreach ($headers as $v) { 126 header($v); 127 } 128 } 105 catch (Exception $e) {} 129 106 } 130 107 } -
plugins/memCache/class.cache.php
r217 r982 2 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 3 # 4 # This file is part of Dotclear 2.4 # This file is part of MemCache, a plugin for Dotclear 2. 5 5 # 6 # Copyright (c) 200 3-2008 Olivier Meunierand contributors6 # Copyright (c) 2008-2009 Alain Vagner, Pep and contributors 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 13 13 class dcMemCache 14 14 { 15 /** 16 * Memcache connexion 17 */ 18 private $con = null; 19 /** 20 * Memcache host 21 */ 22 protected $cache_host; 23 /** 24 * Memcache port 25 */ 26 protected $cache_port; 27 /** 28 * compression active ? 29 */ 30 const compress = 0; 31 /** 32 * expiration? see memcached doc 33 */ 34 const expiration = 0; 15 private $mc = null; 16 protected $memcache_host; 17 protected $memcache_port; 18 protected $memcache_key; 19 protected $memcache_slot; 20 21 public function __construct($uri, $cache_host = 'localhost', $cache_port = 11211, $persist = false) 22 { 23 $this->mc = new Memcache(); 24 $mc_con_func = ($persist) ? 'pconnect' : 'connect'; 25 if (!$this->mc->$mc_con_func($cache_host, $cache_port)) { 26 throw new Exception('cmpCache: Unable to connect to memcached.'); 27 } 28 $this->memcache_host = $cache_host; 29 $this->memcache_port = $cache_port; 30 $this->memcache_key = md5(http::getHost().$uri); 31 } 32 33 public function setBlogMTime($host,$blogid) 34 { 35 $key = md5('bmt:'.$host.':'.$blogid); 36 return $this->mc->set($key,time()); 37 } 35 38 36 public function __construct($cache_host, $cache_port)39 public function getBlogMTime($blogid) 37 40 { 38 $this->con = new Memcache(); 39 if (!$this->con->connect($cache_host, $cache_port)) { 40 throw new Exception('MemCache: Unable to connect to memcached.'); 41 $key = md5('bmt:'.http::getHost().':'.$blogid); 42 return $this->mc->get($key); 43 } 44 45 public function storePage($content_type,$content,$mtime) 46 { 47 $val = array($mtime,$content_type,$content); 48 if (!$this->mc->set($this->memcache_key,serialize($val),false,0)) { 49 throw new Exception('cmpCache: unable to set a value'); 50 } 51 } 52 53 public function fetchPage($mtime) 54 { 55 if ($result = $this->getSlotData()) { 56 $content_mtime = (integer)$result[0]; 57 $content_type = $result[1]; 58 $content = $result[2]; 59 60 if ($mtime > $content_mtime) { 61 return false; 62 } 63 64 header('Content-Type: '.$content_type.'; charset=UTF-8'); 65 header('X-Dotclear-Cmp-Cache: true; mtime: '.date('c',$content_mtime)); 66 echo $content; 67 return true; 68 } 69 return false; 70 } 71 72 public function dropPage() 73 { 74 $this->memcache_slot = null; 75 if (!$this->mc->delete($this->memcache_key,0)) { 76 throw new Exception('cmpCache: unable to drop a page.'); 41 77 } 42 78 } 43 44 public function storePage($key,$content_type,$content,$mtime)79 80 public function getPageMTime() 45 81 { 46 $val = $mtime."|".$content_type."|".$content; 47 if (!$this->con->set(md5($key), $val, self::compress, self::expiration)) {48 throw new Exception('MemCache: unable to set a value');49 } 82 if ($result = $this->getSlotData()) { 83 return (integer)$result[0]; 84 } 85 return false; 50 86 } 51 52 public function fetchPage($key,$mtime)53 {54 $result = $this->con->get(md5($key));55 if (empty($result)) {56 return false;57 }58 $lim = strpos($result, '|');59 $page_mtime = substr($result, 0, $lim);60 $result = substr($result, $lim+1, strlen($result));61 $lim = strpos($result, '|');62 $content_type = substr($result, 0, $lim);63 $content = substr($result, $lim+1, strlen($result));64 65 87 66 if ($mtime > $page_mtime) { 88 protected function getSlotData() 89 { 90 if (!$this->memcache_slot) { 91 $this->memcache_slot = @unserialize($this->mc->get($this->memcache_key)); 92 } 93 if (!$this->memcache_slot || !(is_array($this->memcache_slot) && count($this->memcache_slot) == 3)) { 67 94 return false; 68 95 } 96 return $this->memcache_slot; 97 } 98 99 public static function httpCache($mod_ts=array()) 100 { 101 rsort($mod_ts); 102 $ts = $mod_ts[0]; 69 103 70 header('Content-Type: '.$content_type.'; charset=UTF-8'); 71 header('X-Dotclear-Mem-Cache: true; mtime: '.$page_mtime); 72 echo $content; 73 return true; 74 } 75 76 public function dropPage($key) 77 { 78 if (!$this->con->delete(md5($key))) { 79 throw new Exception('Memcache: unable to drop a page.'); 104 $since = NULL; 105 if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { 106 $since = $_SERVER['HTTP_IF_MODIFIED_SINCE']; 107 $since = preg_replace ('/^(.*)(Mon|Tue|Wed|Thu|Fri|Sat|Sun)(.*)(GMT)(.*)/', '$2$3 GMT', $since); 108 $since = strtotime($since); 80 109 } 81 } 82 83 public function getPageMTime($key) 84 { 85 $result = $this->con->get(md5($key)); 86 if (empty($result)) { 87 return false; 88 } 89 $lim = strpos($result, '|'); 90 return (int) substr($result, 0, $lim); 110 111 # Common headers list 112 $headers[] = 'Last-Modified: '.gmdate('D, d M Y H:i:s',$ts).' GMT'; 113 $headers[] = 'Cache-Control: must-revalidate, max-age=0'; 114 $headers[] = 'Pragma:'; 115 116 if ($since >= $ts) 117 { 118 http::head(304,'Not Modified'); 119 foreach ($headers as $v) { 120 header($v); 121 } 122 exit; 123 } 124 else 125 { 126 header('Date: '.gmdate('D, d M Y H:i:s').' GMT'); 127 foreach ($headers as $v) { 128 header($v); 129 } 130 } 91 131 } 92 132 }
Note: See TracChangeset
for help on using the changeset viewer.