MediaWiki  master
PoolCounter.php
Go to the documentation of this file.
1 <?php
45 abstract class PoolCounter {
46  /* Return codes */
47  public const LOCKED = 1; /* Lock acquired */
48  public const RELEASED = 2; /* Lock released */
49  public const DONE = 3; /* Another worker did the work for you */
50 
51  public const ERROR = -1; /* Indeterminate error */
52  public const NOT_LOCKED = -2; /* Called release() with no lock held */
53  public const QUEUE_FULL = -3; /* There are already maxqueue workers on this lock */
54  public const TIMEOUT = -4; /* Timeout exceeded */
55  public const LOCK_HELD = -5; /* Cannot acquire another lock while you have one lock held */
56 
58  protected $key;
60  protected $workers;
67  protected $slots = 0;
69  protected $maxqueue;
71  protected $timeout;
72 
76  private $isMightWaitKey;
80  private static $acquiredMightWaitKey = 0;
81 
85  private $fastStale;
86 
92  protected function __construct( array $conf, string $type, string $key ) {
93  $this->workers = $conf['workers'];
94  $this->maxqueue = $conf['maxqueue'];
95  $this->timeout = $conf['timeout'];
96  if ( isset( $conf['slots'] ) ) {
97  $this->slots = $conf['slots'];
98  }
99  $this->fastStale = $conf['fastStale'] ?? false;
100 
101  if ( $this->slots ) {
102  $key = $this->hashKeyIntoSlots( $type, $key, $this->slots );
103  }
104 
105  $this->key = $key;
106  $this->isMightWaitKey = !preg_match( '/^nowait:/', $this->key );
107  }
108 
117  public static function factory( string $type, string $key ) {
118  global $wgPoolCounterConf;
119  if ( !isset( $wgPoolCounterConf[$type] ) ) {
120  return new PoolCounterNull;
121  }
122  $conf = $wgPoolCounterConf[$type];
123  $class = $conf['class'];
124 
125  return new $class( $conf, $type, $key );
126  }
127 
131  public function getKey() {
132  return $this->key;
133  }
134 
142  abstract public function acquireForMe( $timeout = null );
143 
152  abstract public function acquireForAnyone( $timeout = null );
153 
161  abstract public function release();
162 
168  final protected function precheckAcquire() {
169  if ( $this->isMightWaitKey ) {
170  if ( self::$acquiredMightWaitKey ) {
171  /*
172  * The poolcounter itself is quite happy to allow you to wait
173  * on another lock while you have a lock you waited on already
174  * but we think that it is unlikely to be a good idea. So we
175  * made it an error. If you are _really_ _really_ sure it is a
176  * good idea then feel free to implement an unsafe flag or
177  * something.
178  */
179  return Status::newFatal( 'poolcounter-usage-error',
180  'You may only aquire a single non-nowait lock.' );
181  }
182  } elseif ( $this->timeout !== 0 ) {
183  return Status::newFatal( 'poolcounter-usage-error',
184  'Locks starting in nowait: must have 0 timeout.' );
185  }
186  return Status::newGood();
187  }
188 
193  final protected function onAcquire() {
194  self::$acquiredMightWaitKey |= $this->isMightWaitKey;
195  }
196 
201  final protected function onRelease() {
202  self::$acquiredMightWaitKey &= !$this->isMightWaitKey;
203  }
204 
217  protected function hashKeyIntoSlots( $type, $key, $slots ) {
218  return $type . ':' . ( hexdec( substr( sha1( $key ), 0, 4 ) ) % $slots );
219  }
220 
221  public function isFastStaleEnabled() {
222  return $this->fastStale;
223  }
224 }
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
PoolCounter\onAcquire
onAcquire()
Update any lock tracking information when the lock is acquired.
Definition: PoolCounter.php:193
PoolCounter\LOCK_HELD
const LOCK_HELD
Definition: PoolCounter.php:55
PoolCounter\NOT_LOCKED
const NOT_LOCKED
Definition: PoolCounter.php:52
PoolCounterNull
A default PoolCounter, which provides no locking.
Definition: PoolCounterNull.php:27
PoolCounter\LOCKED
const LOCKED
Definition: PoolCounter.php:47
PoolCounter\release
release()
I have successfully finished my task.
PoolCounter\$workers
int $workers
Maximum number of workers working on tasks with the same key simultaneously.
Definition: PoolCounter.php:60
PoolCounter\onRelease
onRelease()
Update any lock tracking information when the lock is released.
Definition: PoolCounter.php:201
PoolCounter\$acquiredMightWaitKey
static bool $acquiredMightWaitKey
Whether this process holds a "might wait" lock key.
Definition: PoolCounter.php:80
PoolCounter\acquireForMe
acquireForMe( $timeout=null)
I want to do this task and I need to do it myself.
PoolCounter
When you have many workers (threads/servers) giving service, and a cached item expensive to produce e...
Definition: PoolCounter.php:45
PoolCounter\$isMightWaitKey
bool $isMightWaitKey
Whether the key is a "might wait" key.
Definition: PoolCounter.php:76
PoolCounter\$maxqueue
int $maxqueue
If this number of workers are already working/waiting, fail instead of wait.
Definition: PoolCounter.php:69
PoolCounter\$key
string $key
All workers with the same key share the lock.
Definition: PoolCounter.php:58
PoolCounter\factory
static factory(string $type, string $key)
Create a Pool counter.
Definition: PoolCounter.php:117
PoolCounter\acquireForAnyone
acquireForAnyone( $timeout=null)
I want to do this task, but if anyone else does it instead, it's also fine for me.
PoolCounter\isFastStaleEnabled
isFastStaleEnabled()
Definition: PoolCounter.php:221
PoolCounter\QUEUE_FULL
const QUEUE_FULL
Definition: PoolCounter.php:53
PoolCounter\$fastStale
bool $fastStale
Enable fast stale mode (T250248).
Definition: PoolCounter.php:85
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
PoolCounter\__construct
__construct(array $conf, string $type, string $key)
Definition: PoolCounter.php:92
PoolCounter\ERROR
const ERROR
Definition: PoolCounter.php:51
PoolCounter\$slots
int $slots
Maximum number of workers working on this task type, regardless of key.
Definition: PoolCounter.php:67
PoolCounter\getKey
getKey()
Definition: PoolCounter.php:131
$wgPoolCounterConf
$wgPoolCounterConf
Configuration for processing pool control, for use in high-traffic wikis.
Definition: DefaultSettings.php:9072
PoolCounter\hashKeyIntoSlots
hashKeyIntoSlots( $type, $key, $slots)
Given a key (any string) and the number of lots, returns a slot key (a prefix with a suffix integer f...
Definition: PoolCounter.php:217
PoolCounter\RELEASED
const RELEASED
Definition: PoolCounter.php:48
PoolCounter\TIMEOUT
const TIMEOUT
Definition: PoolCounter.php:54
PoolCounter\precheckAcquire
precheckAcquire()
Checks that the lock request is sane.
Definition: PoolCounter.php:168
PoolCounter\DONE
const DONE
Definition: PoolCounter.php:49
PoolCounter\$timeout
int $timeout
Maximum time in seconds to wait for the lock.
Definition: PoolCounter.php:71
$type
$type
Definition: testCompression.php:52