12 private static $servers;
13 private static $working;
21 if ( isset(self::$working) )
return;
23 self::$working =
false;
24 if ( ! isset($c->memcache_servers) ) {
25 dbg_error_log(
'Cache',
"memcache_servers isn't set, using NoCache dummy interface");
27 }
else if (! is_array($c->memcache_servers) ) {
28 dbg_error_log(
'Cache',
"memcache_servers must be an array, using NoCache dummy interface");
32 if (! class_exists(
'Memcached') ) {
33 dbg_error_log(
'Cache',
"Memcached class isn't available, using NoCache dummy interface");
37 dbg_error_log(
'Cache',
'Using Memcached interface connection');
38 self::$servers = $c->memcache_servers;
39 self::$m =
new Memcached();
40 foreach( self::$servers AS $v ) {
41 dbg_error_log(
'Cache',
'Adding server '.$v);
42 $server = explode(
',',$v);
43 if ( isset($server[2]) )
44 self::$m->addServer($server[0],$server[1],$server[2]);
46 self::$m->addServer($server[0],$server[1]);
48 self::$working =
true;
51 if ( isset($_SERVER[
'HTTP_X_DAVICAL_FLUSH_CACHE'])) $this->
flush();
58 return self::$working;
66 private function nskey( $namespace, $key ) {
67 return str_replace(
' ',
'%20', $namespace . (isset($key) ?
'~~' . $key:
''));
75 function get( $namespace, $key ) {
76 if ( !self::$working )
return false;
78 $value = self::$m->get($ourkey);
91 function set( $namespace, $key, $value, $expiry=864000 ) {
92 if ( !self::$working )
return false;
97 if (defined(
'Memcached::GET_EXTENDED')) {
98 $result = self::$m->get( $nskey,
null, Memcached::GET_EXTENDED);
100 if (is_array($result)) {
101 $keylist = $result[
'value'];
102 $cas_token = $result[
'cas'];
105 $keylist = self::$m->get( $nskey,
null, $cas_token );
108 if ( isset($keylist) && is_array($keylist) ) {
109 if ( !isset($keylist[$ourkey]) ) {
110 $keylist[$ourkey] = 1;
111 $success = self::$m->cas( $cas_token, $nskey, $keylist );
114 while( !$success && $i++ < 10 && self::$m->getResultCode() == Memcached::RES_DATA_EXISTS ) {
116 if (defined(
'Memcached::GET_EXTENDED')) {
117 $result = self::$m->get( $nskey,
null, Memcached::GET_EXTENDED);
118 if (is_array($result)) {
119 $keylist = $result[
'value'];
120 $cas_token = $result[
'cas'];
123 $keylist = self::$m->get( $nskey,
null, $cas_token );
126 if ( $keylist ===
false )
return false;
127 if ( isset($keylist[$ourkey]) )
break;
129 $keylist[$ourkey] = 1;
130 $success = self::$m->cas( $cas_token, $nskey, $keylist );
132 if ( !$success )
return false;
136 $keylist = array( $ourkey => 1 );
137 self::$m->set( $nskey, $keylist );
141 return self::$m->set( $ourkey, $value, $expiry );
149 function delete( $namespace, $key ) {
150 if ( !self::$working )
return false;
152 dbg_error_log(
'Cache',
'Deleting from cache key "'.$nskey.
'"');
155 self::$m->delete( $nskey );
158 if (defined(
'Memcached::GET_EXTENDED')) {
159 $result = self::$m->get( $nskey,
null, Memcached::GET_EXTENDED);
160 if (is_array($result)) {
161 $keylist = $result[
'value'];
162 $cas_token = $result[
'cas'];
165 $keylist = self::$m->get( $nskey,
null, $cas_token );
167 if ( isset($keylist) ) {
168 self::$m->delete( $nskey );
169 if ( is_array($keylist) ) {
170 foreach( $keylist AS $k => $v ) self::$m->delete( $k );
180 if ( !self::$working )
return false;
181 dbg_error_log(
'Cache',
'Flushing cache');
190 if ( !self::$working )
return $something;
191 $wait_until = time() + $wait_for;
192 while( self::$m->add(
'_lock_' . $something, 1, 5) ===
false && time() < $wait_until ) {
203 if ( !self::$working )
return;
204 self::$m->delete(
'_lock_' . $something);
209function getCacheInstance() {
210 static $ourCacheInstance;
212 if ( !isset($ourCacheInstance) ) $ourCacheInstance =
new AWLCache(
'Memcached');
214 return $ourCacheInstance;
acquireLock( $something, $wait_for=5)