| [ Index ] |
PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008] |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 ** This class abstracts eaccelerator/turckmmcache 4 ** API to provide 5 ** 6 ** - get() 7 ** - set() 8 ** - delete() 9 ** - getforfill() 10 ** - releaseforfill() 11 ** 12 ** Author: Martin Langhoff <martin@catalyst.net.nz> 13 ** 14 ** Note: do NOT store booleans here. For compatibility with 15 ** memcached, a false value is indistinguisable from a 16 ** "not found in cache" response. 17 **/ 18 19 20 class eaccelerator { 21 22 function eaccelerator() { 23 global $CFG; 24 if ( function_exists('eaccelerator_get')) { 25 $this->mode = 'eaccelerator'; 26 } elseif (function_exists('mmcache_get')) { 27 $this->mode = 'mmcache'; 28 } else { 29 debugging("\$CFG->eaccelerator is set to true but the required functions are not available. You need to have either eaccelerator or turckmmcache extensions installed, compiled with the shmem keys option enabled."); 30 } 31 32 $this->prefix = $CFG->dbname .'|' . $CFG->prefix . '|'; 33 } 34 35 function status() { 36 if (isset($this->mode)) { 37 return true; 38 } 39 return false; 40 } 41 42 function set($key, $value, $ttl=0) { 43 $set = $this->mode . '_put'; 44 $unlock = $this->mode . '_unlock'; 45 46 // we may have acquired a lock via getforfill 47 // release if it exists 48 @$unlock($this->prefix . $key . '_forfill'); 49 50 return $set($this->prefix . $key, serialize($value), $ttl); 51 } 52 53 function get($key) { 54 $fn = $this->mode . '_get'; 55 $rec = $fn($this->prefix . $key); 56 if (is_null($rec)) { 57 return false; 58 } 59 return unserialize($rec); 60 } 61 62 function delete($key) { 63 $fn = $this->mode . '_rm'; 64 return $fn($this->prefix . $key); 65 } 66 67 /** 68 * In the simple case, this function will 69 * get the cached value if available. If the entry 70 * is not cached, it will try to get an exclusive 71 * lock that announces that this process will 72 * populate the cache. 73 * 74 * If we fail to get the lock -- this means another 75 * process is doing it. 76 * so we wait (block) for a few microseconds while we wait for 77 * the cache to be filled or the lock to timeout. 78 * 79 * If you get a false from this call, you _must_ 80 * populate the cache ASAP or indicate that 81 * you won't by calling releaseforfill(). 82 * 83 * This technique forces serialisation and so helps deal 84 * with thundering herd scenarios where a lot of clients 85 * ask the for the same idempotent (and costly) operation. 86 * The implementation is based on suggestions in this message 87 * http://marc.theaimsgroup.com/?l=git&m=116562052506776&w=2 88 * 89 * @param $key string 90 * @return mixed on cache hit, false otherwise 91 */ 92 function getforfill ($key) { 93 $get = $this->mode . '_get'; 94 $lock = $this->mode . '_lock'; 95 96 $rec = $get($this->prefix . $key); 97 if (!is_null($rec)) { 98 return unserialize($rec); 99 } 100 if ($lock($this->prefix . $key . '_forfill')) { 101 // we obtained the _forfill lock 102 // our caller will compute and set the value 103 return false; 104 } 105 // someone else has the lock 106 // "block" till we can get the value 107 // actually, loop .05s waiting for it 108 for ($n=0;$n<5;$n++) { 109 usleep(10000); 110 $rec = $get($this->prefix . $key); 111 if (!is_null($rec)) { 112 return unserialize($rec); 113 } 114 } 115 return false; 116 } 117 118 /** 119 * Release the exclusive lock obtained by 120 * getforfill(). See getforfill() 121 * for more details. 122 * 123 * @param $key string 124 * @return bool 125 */ 126 function releaseforfill ($key) { 127 $unlock = $this->mode . '_unlock'; 128 return $unlock($this->prefix . $key . '_forfill'); 129 } 130 } 131 132 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 14 11:33:29 2009 | Cross-referenced by PHPXref 0.7 |