MediaWiki master
PoolCounterWork.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\PoolCounter;
22
25
29abstract class PoolCounterWork {
31 protected $type = 'generic';
33 protected $cacheable = false; // does this override getCachedWork() ?
35 private $poolCounter;
36
42 public function __construct( string $type, string $key, PoolCounter $poolCounter = null ) {
43 $this->type = $type;
44 // MW >= 1.35
45 $this->poolCounter = $poolCounter ??
46 MediaWikiServices::getInstance()->getPoolCounterFactory()->create( $type, $key );
47 }
48
54 abstract public function doWork();
55
61 public function getCachedWork() {
62 return false;
63 }
64
72 public function fallback( $fast ) {
73 return false;
74 }
75
82 public function error( $status ) {
83 return false;
84 }
85
91 protected function isFastStaleEnabled() {
92 return $this->poolCounter->isFastStaleEnabled();
93 }
94
101 public function logError( $status ) {
102 $key = $this->poolCounter->getKey();
103
104 $this->poolCounter->getLogger()->info(
105 "Pool key '$key' ({$this->type}): " .
106 $status->getMessage()->inLanguage( 'en' )->useDatabase( false )->text()
107 );
108 }
109
137 public function execute( $skipcache = false ) {
138 if ( !$this->cacheable || $skipcache ) {
139 $status = $this->poolCounter->acquireForMe();
140 } else {
141 if ( $this->isFastStaleEnabled() ) {
142 // In fast stale mode, check for existing locks by acquiring lock with 0 timeout
143 $status = $this->poolCounter->acquireForAnyone( 0 );
144 if ( $status->isOK() && $status->value === PoolCounter::TIMEOUT ) {
145 // Lock acquisition would block: try fallback
146 $staleResult = $this->fallback( true );
147 if ( $staleResult !== false ) {
148 return $staleResult;
149 }
150 // No fallback available, so wait for the lock
151 $status = $this->poolCounter->acquireForAnyone();
152 } // else behave as if $status were returned in slow mode
153 } else {
154 $status = $this->poolCounter->acquireForAnyone();
155 }
156 }
157
158 if ( !$status->isOK() ) {
159 // Respond gracefully to complete server breakage: just log it and do the work
160 $this->logError( $status );
161 return $this->doWork();
162 }
163
164 switch ( $status->value ) {
166 // Better to ignore nesting pool counter limits than to fail.
167 // Assume that the outer pool limiting is reasonable enough.
168 /* no break */
170 try {
171 return $this->doWork();
172 } finally {
173 $this->poolCounter->release();
174 }
175 // no fall-through, because try returns or throws
177 $result = $this->getCachedWork();
178 if ( $result === false ) {
179 /* That someone else work didn't serve us.
180 * Acquire the lock for me
181 */
182 return $this->execute( true );
183 }
184 return $result;
185
188 $result = $this->fallback( false );
189
190 if ( $result !== false ) {
191 return $result;
192 }
193 /* no break */
194
195 /* These two cases should never be hit... */
197 default:
198 $errors = [
199 PoolCounter::QUEUE_FULL => 'pool-queuefull',
200 PoolCounter::TIMEOUT => 'pool-timeout',
201 ];
202
203 $status = Status::newFatal( $errors[$status->value] ?? 'pool-errorunknown' );
204 $this->logError( $status );
205 return $this->error( $status );
206 }
207 }
208}
209
211class_alias( PoolCounterWork::class, 'PoolCounterWork' );
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Class for dealing with PoolCounters using class members.
doWork()
Actually perform the work, caching it if needed.
error( $status)
Do something with the error, like showing it to the user.
execute( $skipcache=false)
Get the result of the work (whatever it is), or the result of the error() function.
__construct(string $type, string $key, PoolCounter $poolCounter=null)
fallback( $fast)
A work not so good (eg.
isFastStaleEnabled()
Should fast stale mode be used?
getCachedWork()
Retrieve the work from cache.
Semaphore semantics to restrict how many workers may concurrently perform a task.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54