Aaron Schulz has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/181209

Change subject: Moved "nowait:" key code to PoolCounter in core
......................................................................

Moved "nowait:" key code to PoolCounter in core

Change-Id: I5286e6c6052289e1107314a04d72703b44a8fbc6
---
M includes/poolcounter/PoolCounter.php
M includes/poolcounter/PoolCounterRedis.php
2 files changed, 70 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/09/181209/1

diff --git a/includes/poolcounter/PoolCounter.php 
b/includes/poolcounter/PoolCounter.php
index e77ffd7..5692d73 100644
--- a/includes/poolcounter/PoolCounter.php
+++ b/includes/poolcounter/PoolCounter.php
@@ -34,7 +34,10 @@
  * minutes and hundreds of read hits.
  *
  * The PoolCounter provides semaphore semantics for restricting the number
- * of workers that may be concurrently performing such single task.
+ * of workers that may be concurrently performing such single task. Only one
+ * key can be locked by any PoolCounter instance of a process, except for keys
+ * that start with "nowait:". However, only 0 timeouts (non-blocking requests)
+ * can be used with "nowait:" keys.
  *
  * By default PoolCounter_Stub is used, which provides no locking. You
  * can get a useful one in the PoolCounter extension.
@@ -68,6 +71,15 @@
        protected $timeout;
 
        /**
+        * @var boolean Whether the key is a "might wait" key
+        */
+       private $isMightWaitKey;
+       /**
+        * @var boolean Whether this process holds a "might wait" lock key
+        */
+       private static $acquiredMightWaitKey = 0;
+
+       /**
         * @param array $conf
         * @param string $type
         * @param string $key
@@ -84,6 +96,7 @@
                        $key = $this->hashKeyIntoSlots( $key, $this->slots );
                }
                $this->key = $key;
+               $this->isMightWaitKey = !preg_match( '/^nowait:/', $this->key );
        }
 
        /**
@@ -137,6 +150,48 @@
        abstract public function release();
 
        /**
+        * Checks that the lock request is sane.
+        * @return Status - good for sane requests fatal for insane
+        * @since 1.25
+        */
+       final protected function precheckAcquire() {
+               if ( $this->isMightWaitKey ) {
+                       if ( self::$acquiredMightWaitKey ) {
+                               /*
+                                * The poolcounter itself is quite happy to 
allow you to wait
+                                * on another lock while you have a lock you 
waited on already
+                                * but we think that it is unlikely to be a 
good idea.  So we
+                                * made it an error.  If you are _really_ 
_really_ sure it is a
+                                * good idea then feel free to implement an 
unsafe flag or
+                                * something.
+                                */
+                               return Status::newFatal( 
'poolcounter-usage-error',
+                                       'You may only aquire a single 
non-nowait lock.' );
+                       }
+               } elseif ( $this->timeout !== 0 ) {
+                       return Status::newFatal( 'poolcounter-usage-error',
+                               'Locks starting in nowait: must have 0 
timeout.' );
+               }
+               return Status::newGood();
+       }
+
+       /**
+        * Update any lock tracking information when the lock is acquired
+        * @since 1.25
+        */
+       final protected function onAcquire() {
+               self::$acquiredMightWaitKey |= $this->isMightWaitKey;
+       }
+
+       /**
+        * Update any lock tracking information when the lock is released
+        * @since 1.25
+        */
+       final protected function onRelease() {
+               self::$acquiredMightWaitKey &= !$this->isMightWaitKey;
+       }
+
+       /**
         * Given a key (any string) and the number of lots, returns a slot 
number (an integer from the [0..($slots-1)] range).
         * This is used for a global limit on the number of instances  of a 
given type that can acquire a lock.
         * The hashing is deterministic so that PoolCounter::$workers is always 
an upper limit of how many instances with
diff --git a/includes/poolcounter/PoolCounterRedis.php 
b/includes/poolcounter/PoolCounterRedis.php
index d609f61..0f025f3 100644
--- a/includes/poolcounter/PoolCounterRedis.php
+++ b/includes/poolcounter/PoolCounterRedis.php
@@ -123,11 +123,21 @@
        function acquireForMe() {
                $section = new ProfileSection( __METHOD__ );
 
+               $status = $this->precheckAcquire();
+               if ( !$status->isGood() ) {
+                       return $status;
+               }
+
                return $this->waitForSlotOrNotif( self::AWAKE_ONE );
        }
 
        function acquireForAnyone() {
                $section = new ProfileSection( __METHOD__ );
+
+               $status = $this->precheckAcquire();
+               if ( !$status->isGood() ) {
+                       return $status;
+               }
 
                return $this->waitForSlotOrNotif( self::AWAKE_ALL );
        }
@@ -207,6 +217,8 @@
                $this->onRelease = null;
                unset( self::$active[$this->session] );
 
+               $this->onRelease();
+
                return Status::newGood( PoolCounter::RELEASED );
        }
 
@@ -266,6 +278,8 @@
                        self::$active[$this->session] = $this;
                }
 
+               $this->onAcquire();
+
                return Status::newGood( $slot === 'w' ? PoolCounter::DONE : 
PoolCounter::LOCKED );
        }
 

-- 
To view, visit https://gerrit.wikimedia.org/r/181209
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5286e6c6052289e1107314a04d72703b44a8fbc6
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <asch...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to