MediaWiki  REL1_23
PoolCounterWork.php
Go to the documentation of this file.
00001 <?php
00027 abstract class PoolCounterWork {
00028     protected $cacheable = false; //Does this override getCachedWork() ?
00029 
00034     public function __construct( $type, $key ) {
00035         $this->poolCounter = PoolCounter::factory( $type, $key );
00036     }
00037 
00042     abstract public function doWork();
00043 
00048     public function getCachedWork() {
00049         return false;
00050     }
00051 
00057     public function fallback() {
00058         return false;
00059     }
00060 
00065     public function error( $status ) {
00066         return false;
00067     }
00068 
00075     public function logError( $status ) {
00076         $key = $this->poolCounter->getKey();
00077 
00078         wfDebugLog( 'poolcounter', "Pool key '$key': "
00079             . $status->getMessage()->inLanguage( 'en' )->useDatabase( false )->text() );
00080     }
00081 
00097     public function execute( $skipcache = false ) {
00098         if ( $this->cacheable && !$skipcache ) {
00099             $status = $this->poolCounter->acquireForAnyone();
00100         } else {
00101             $status = $this->poolCounter->acquireForMe();
00102         }
00103 
00104         if ( !$status->isOK() ) {
00105             // Respond gracefully to complete server breakage: just log it and do the work
00106             $this->logError( $status );
00107             return $this->doWork();
00108         }
00109 
00110         switch ( $status->value ) {
00111             case PoolCounter::LOCKED:
00112                 $result = $this->doWork();
00113                 $this->poolCounter->release();
00114                 return $result;
00115 
00116             case PoolCounter::DONE:
00117                 $result = $this->getCachedWork();
00118                 if ( $result === false ) {
00119                     /* That someone else work didn't serve us.
00120                      * Acquire the lock for me
00121                      */
00122                     return $this->execute( true );
00123                 }
00124                 return $result;
00125 
00126             case PoolCounter::QUEUE_FULL:
00127             case PoolCounter::TIMEOUT:
00128                 $result = $this->fallback();
00129 
00130                 if ( $result !== false ) {
00131                     return $result;
00132                 }
00133                 /* no break */
00134 
00135             /* These two cases should never be hit... */
00136             case PoolCounter::ERROR:
00137             default:
00138                 $errors = array(
00139                     PoolCounter::QUEUE_FULL => 'pool-queuefull',
00140                     PoolCounter::TIMEOUT => 'pool-timeout' );
00141 
00142                 $status = Status::newFatal( isset( $errors[$status->value] )
00143                     ? $errors[$status->value]
00144                     : 'pool-errorunknown' );
00145                 $this->logError( $status );
00146                 return $this->error( $status );
00147         }
00148     }
00149 }
00150 
00155 class PoolCounterWorkViaCallback extends PoolCounterWork {
00157     protected $doWork;
00159     protected $doCachedWork;
00161     protected $fallback;
00163     protected $error;
00164 
00179     public function __construct( $type, $key, array $callbacks ) {
00180         parent::__construct( $type, $key );
00181         foreach ( array( 'doWork', 'doCachedWork', 'fallback', 'error' ) as $name ) {
00182             if ( isset( $callbacks[$name] ) ) {
00183                 if ( !is_callable( $callbacks[$name] ) ) {
00184                     throw new MWException( "Invalid callback provided for '$name' function." );
00185                 }
00186                 $this->$name = $callbacks[$name];
00187             }
00188         }
00189         if ( !isset( $this->doWork ) ) {
00190             throw new MWException( "No callback provided for 'doWork' function." );
00191         }
00192         $this->cacheable = isset( $this->doCachedWork );
00193     }
00194 
00195     public function doWork() {
00196         return call_user_func_array( $this->doWork, array() );
00197     }
00198 
00199     public function getCachedWork() {
00200         if ( $this->doCachedWork ) {
00201             return call_user_func_array( $this->doCachedWork, array() );
00202         }
00203         return false;
00204     }
00205 
00206     public function fallback() {
00207         if ( $this->fallback ) {
00208             return call_user_func_array( $this->fallback, array() );
00209         }
00210         return false;
00211     }
00212 
00213     public function error( $status ) {
00214         if ( $this->error ) {
00215             return call_user_func_array( $this->error, array( $status ) );
00216         }
00217         return false;
00218     }
00219 }