MediaWiki  master
PoolCounterWork.php
Go to the documentation of this file.
1 <?php
27 abstract class PoolCounterWork {
29  protected $type = 'generic';
31  protected $cacheable = false; // does this override getCachedWork() ?
33  private $poolCounter;
34 
39  public function __construct( $type, $key ) {
40  $this->type = $type;
41  $this->poolCounter = PoolCounter::factory( $type, $key );
42  }
43 
48  abstract public function doWork();
49 
54  public function getCachedWork() {
55  return false;
56  }
57 
63  public function fallback() {
64  return false;
65  }
66 
74  public function error( $status ) {
75  return false;
76  }
77 
84  public function logError( $status ) {
85  $key = $this->poolCounter->getKey();
86 
87  wfDebugLog( 'poolcounter', "Pool key '$key' ({$this->type}): "
88  . $status->getMessage()->inLanguage( 'en' )->useDatabase( false )->text() );
89  }
90 
106  public function execute( $skipcache = false ) {
107  if ( $this->cacheable && !$skipcache ) {
108  $status = $this->poolCounter->acquireForAnyone();
109  } else {
110  $status = $this->poolCounter->acquireForMe();
111  }
112 
113  if ( !$status->isOK() ) {
114  // Respond gracefully to complete server breakage: just log it and do the work
115  $this->logError( $status );
116  return $this->doWork();
117  }
118 
119  switch ( $status->value ) {
121  // Better to ignore nesting pool counter limits than to fail.
122  // Assume that the outer pool limiting is reasonable enough.
123  /* no break */
124  case PoolCounter::LOCKED:
125  $result = $this->doWork();
126  $this->poolCounter->release();
127  return $result;
128 
129  case PoolCounter::DONE:
130  $result = $this->getCachedWork();
131  if ( $result === false ) {
132  /* That someone else work didn't serve us.
133  * Acquire the lock for me
134  */
135  return $this->execute( true );
136  }
137  return $result;
138 
141  $result = $this->fallback();
142 
143  if ( $result !== false ) {
144  return $result;
145  }
146  /* no break */
147 
148  /* These two cases should never be hit... */
149  case PoolCounter::ERROR:
150  default:
151  $errors = [
152  PoolCounter::QUEUE_FULL => 'pool-queuefull',
153  PoolCounter::TIMEOUT => 'pool-timeout' ];
154 
155  $status = Status::newFatal( $errors[$status->value] ?? 'pool-errorunknown' );
156  $this->logError( $status );
157  return $this->error( $status );
158  }
159  }
160 }
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:69
fallback()
A work not so good (eg.
const LOCKED
Definition: PoolCounter.php:47
getCachedWork()
Retrieve the work from cache.
execute( $skipcache=false)
Get the result of the work (whatever it is), or the result of the error() function.
doWork()
Actually perform the work, caching it if needed.
error( $status)
Do something with the error, like showing it to the user.
static factory( $type, $key)
Create a Pool counter.
__construct( $type, $key)
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not...
const QUEUE_FULL
Definition: PoolCounter.php:53
PoolCounter $poolCounter
const TIMEOUT
Definition: PoolCounter.php:54
Class for dealing with PoolCounters using class members.
logError( $status)
Log an error.
const LOCK_HELD
Definition: PoolCounter.php:55