|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00025 defined('MOODLE_INTERNAL') || die(); 00026 00046 class memcached { 00047 00048 function memcached() { 00049 global $CFG; 00050 00051 if (!function_exists('memcache_connect')) { 00052 debugging("Memcached is set to true but the memcached extension is not installed"); 00053 return false; 00054 } 00055 $this->_cache = new Memcache; 00056 00057 $hosts = explode(',', $CFG->memcachedhosts); 00058 if (count($hosts) === 1 && !empty($CFG->memcachedpconn)) { 00059 // the faster pconnect is only available 00060 // for single-server setups 00061 // NOTE: PHP-PECL client is buggy and pconnect() 00062 // will segfault if the server is unavailable 00063 $this->_cache->pconnect($hosts[0]); 00064 } else { 00065 // multi-host setup will share key space 00066 foreach ($hosts as $host) { 00067 $host = trim($host); 00068 $this->_cache->addServer($host); 00069 } 00070 } 00071 00072 $this->prefix = $CFG->dbname .'|' . $CFG->prefix . '|'; 00073 } 00074 00075 function status() { 00076 if (is_object($this->_cache)) { 00077 return true; 00078 } 00079 return false; 00080 } 00081 00082 function set($key, $value, $ttl=0) { 00083 00084 // we may have acquired a lock via getforfill 00085 // release if it exists 00086 @$this->_cache->delete($this->prefix . $key . '_forfill'); 00087 00088 return $this->_cache->set($this->prefix . $key, $value, false); 00089 } 00090 00091 function get($key) { 00092 $rec = $this->_cache->get($this->prefix . $key); 00093 return $rec; 00094 } 00095 00096 function delete($key) { 00097 return $this->_cache->delete($this->prefix . $key); 00098 } 00099 00125 function getforfill ($key) { 00126 00127 $rec = $this->_cache->get($this->prefix . $key); 00128 if ($rec) { 00129 return $rec; 00130 } 00131 if ($this->_cache->add($this->prefix . $key . '_forfill', 'true', false, 1)) { 00132 // we obtained the _forfill lock 00133 // our caller will compute and set the value 00134 return false; 00135 } 00136 // someone else has the lock 00137 // "block" till we can get the value 00138 // actually, loop .05s waiting for it 00139 for ($n=0;$n<5;$n++) { 00140 usleep(10000); 00141 $rec = $this->_cache->get($this->prefix . $key); 00142 if ($rec) { 00143 return $rec; 00144 } 00145 } 00146 return false; 00147 } 00148 00157 function releaseforfill ($key) { 00158 return $this->_cache->delete($this->prefix . $key . '_forfill'); 00159 } 00160 }