Back to index

awl  0.53
AwlCache.php
Go to the documentation of this file.
00001 <?php
00002 
00010 class AwlCache {
00011   private static $m;
00012   private static $servers;
00013   private static $working;
00014 
00018   function __construct() {
00019     global $c;
00020 
00021     if ( isset(self::$working) ) return;
00022 
00023     self::$working = false;
00024     if ( isset($c->memcache_servers) && class_exists('Memcached') ) {
00025       dbg_error_log('Cache', 'Using Memcached interface connection');
00026       self::$servers = $c->memcache_servers;
00027       self::$m = new Memcached();
00028       foreach( self::$servers AS $v ) {
00029         dbg_error_log('Cache', 'Adding server '.$v);
00030         $server = explode(',',$v);
00031         if ( isset($server[2]) )
00032           self::$m->addServer($server[0],$server[1],$server[2]);
00033         else
00034           self::$m->addServer($server[0],$server[1]);
00035       }
00036       self::$working = true;
00037       // Hack to allow the regression tests to flush the cache at start
00038       if ( isset($_SERVER['HTTP_X_DAVICAL_FLUSH_CACHE'])) $this->flush();
00039     }
00040     else {
00041       dbg_error_log('Cache', 'Using NoCache dummy interface');
00042     }
00043   }
00044 
00048   function isActive() {
00049     return self::$working;
00050   }
00051 
00057   private function nskey( $namespace, $key ) {
00058     return str_replace(' ', '%20', $namespace . (isset($key) ? '~~' . $key: '')); // for now.
00059   }
00060 
00066   function get( $namespace, $key ) {
00067     if ( !self::$working ) return false;
00068     $ourkey = self::nskey($namespace,$key);
00069     $value = self::$m->get($ourkey);
00070 //    var_dump($value);
00071 //    if ( $value !== false ) dbg_error_log('Cache', 'Got value for cache key "'.$ourkey.'" - '.strlen(serialize($value)).' bytes');
00072     return $value;
00073   }
00074 
00082   function set( $namespace, $key, $value, $expiry=864000 ) {
00083     if ( !self::$working ) return false;
00084     $ourkey = self::nskey($namespace,$key);
00085     $nskey = self::nskey($namespace,null);
00086     $keylist = self::$m->get( $nskey, null, $cas_token );
00087     if ( isset($keylist) && is_array($keylist) ) {
00088       if ( !isset($keylist[$ourkey]) ) {
00089         $keylist[$ourkey] = 1;
00090         $success = self::$m->cas( $cas_token, $nskey, $keylist );
00091         $i=0;
00092         while( !$success && $i++ < 10 && self::$m->getResultCode() == Memcached::RES_DATA_EXISTS ) {
00093           $keylist = self::$m->get( $nskey, null, $cas_token );
00094           if ( $keylist === false ) return false;
00095           if ( isset($keylist[$ourkey]) ) break;
00096           $keylist[$ourkey] = 1;
00097           $success = self::$m->cas( $cas_token, $nskey, $keylist );
00098         }
00099         if ( !$success ) return false;
00100       }
00101     } 
00102     else {
00103       $keylist = array( $ourkey => 1 );      
00104       self::$m->set( $nskey, $keylist );
00105     }
00106 //    var_dump($value);
00107 //    dbg_error_log('Cache', 'Setting value for cache key "'.$ourkey.'" - '.strlen(serialize($value)).' bytes');
00108     return self::$m->set( $ourkey, $value, $expiry );
00109   }
00110 
00116   function delete( $namespace, $key ) {
00117     if ( !self::$working ) return false;
00118     $nskey = self::nskey($namespace,$key);
00119     dbg_error_log('Cache', 'Deleting from cache key "'.$nskey.'"');
00120     if ( isset($key) ) {
00121       self::$m->delete( $nskey );
00122     }
00123     else {
00124       $keylist = self::$m->get( $nskey, null, $cas_token );
00125       if ( isset($keylist) ) {
00126       self::$m->delete( $nskey );
00127         if ( is_array($keylist) ) {
00128           foreach( $keylist AS $k => $v ) self::$m->delete( $k );
00129         } 
00130       }
00131     }
00132   }
00133 
00137   function flush( ) {
00138     if ( !self::$working ) return false;
00139     dbg_error_log('Cache', 'Flushing cache');
00140     self::$m->flush();
00141   }
00142 
00143   
00147   function acquireLock( $something, $wait_for = 5 ) {
00148     if ( !self::$working ) return $something;
00149     $wait_until = time() + $wait_for;
00150     while( self::$m->add('_lock_'+$something,1,5) === false && time() < $wait_until ) {
00151       usleep(10000);
00152     }
00153     return $something;
00154   }
00155 
00156   
00160   function releaseLock( $something ) {
00161     if ( !self::$working ) return;
00162     self::$m->delete('_lock_'+$something);        
00163   }
00164 }
00165 
00166 
00167 function getCacheInstance() {
00168   static $ourCacheInstance;
00169 
00170   if ( !isset($ourCacheInstance) ) $ourCacheInstance = new AWLCache('Memcached'); 
00171 
00172   return $ourCacheInstance;
00173 }