3 ** This class abstracts eaccelerator/turckmmcache
12 ** Author: Martin Langhoff <martin@catalyst.net.nz>
19 function eaccelerator() {
21 if ( function_exists('eaccelerator_get')) {
22 $mode = 'eaccelerator';
23 } elseif (function_exists('mmcache_get')) {
26 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 $this->prefix = $CFG->dbname .'|' . $CFG->prefix . '|';
34 if (isset($this->mode)) {
40 function set($key, $value, $ttl=0) {
41 $set = $this->mode . '_put';
42 $unlock = $this->mode . '_unlock';
44 // we may have acquired a lock via getforfill
45 // release if it exists
46 @$unlock($this->prefix . $key . '_forfill');
48 return $set($this->prefix . $key, serialize($value), $ttl);
52 $fn = $this->mode . '_get';
53 $rec = $fn($this->prefix . $key);
57 return unserialize($rec);
60 function delete($key) {
61 $fn = $this->mode . '_rm';
62 return $fn($this->prefix . $key);
66 * In the simple case, this function will
67 * get the cached value if available. If the entry
68 * is not cached, it will try to get an exclusive
69 * lock that announces that this process will
72 * If we fail to get the lock -- this means another
73 * process is doing it.
74 * so we wait (block) for a few microseconds while we wait for
75 * the cache to be filled or the lock to timeout.
77 * If you get a false from this call, you _must_
78 * populate the cache ASAP or indicate that
79 * you won't by calling releaseforfill().
81 * This technique forces serialisation and so helps deal
82 * with thundering herd scenarios where a lot of clients
83 * ask the for the same idempotent (and costly) operation.
84 * The implementation is based on suggestions in this message
85 * http://marc.theaimsgroup.com/?l=git&m=116562052506776&w=2
88 * @return mixed on cache hit, NULL otherwise
90 function getforfill ($key) {
91 $get = $this->mode . '_get';
92 $lock = $this->mode . '_lock';
94 $rec = $get($this->prefix . $key);
96 return unserialize($rec);
98 if ($lock($this->prefix . $key . '_forfill')) {
99 // we obtained the _forfill lock
100 // our caller will compute and set the value
103 // someone else has the lock
104 // "block" till we can get the value
105 // actually, loop .05s waiting for it
106 for ($n=0;$n<5;$n++) {
108 $rec = $get($this->prefix . $key);
109 if (!is_null($rec)) {
110 return unserialize($rec);
117 * Release the exclusive lock obtained by
118 * getforfill(). See getforfill()
124 function releaseforfill ($key) {
125 $unlock = $this->mode . '_unlock';
126 return $unlock($this->prefix . $key . '_forfill');