Przeglądaj źródła

Log more info about locking conflicts for memcache locking backends

Signed-off-by: Robin Appelman <robin@icewind.nl>
Robin Appelman 6 lat temu
rodzic
commit
25565dd7d8

+ 15 - 4
lib/private/Lock/MemcacheLockingProvider.php

@@ -72,12 +72,12 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
 	public function acquireLock(string $path, int $type) {
 		if ($type === self::LOCK_SHARED) {
 			if (!$this->memcache->inc($path)) {
-				throw new LockedException($path);
+				throw new LockedException($path, null, $this->getExistingLockForException($path));
 			}
 		} else {
 			$this->memcache->add($path, 0);
 			if (!$this->memcache->cas($path, 0, 'exclusive')) {
-				throw new LockedException($path);
+				throw new LockedException($path, null, $this->getExistingLockForException($path));
 			}
 		}
 		$this->setTTL($path);
@@ -115,15 +115,26 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
 	public function changeLock(string $path, int $targetType) {
 		if ($targetType === self::LOCK_SHARED) {
 			if (!$this->memcache->cas($path, 'exclusive', 1)) {
-				throw new LockedException($path);
+				throw new LockedException($path, null, $this->getExistingLockForException($path));
 			}
 		} else if ($targetType === self::LOCK_EXCLUSIVE) {
 			// we can only change a shared lock to an exclusive if there's only a single owner of the shared lock
 			if (!$this->memcache->cas($path, 1, 'exclusive')) {
-				throw new LockedException($path);
+				throw new LockedException($path, null, $this->getExistingLockForException($path));
 			}
 		}
 		$this->setTTL($path);
 		$this->markChange($path, $targetType);
 	}
+
+	private function getExistingLockForException($path) {
+		$existing = $this->memcache->get($path);
+		if (!$existing) {
+			return 'none';
+		} else if ($existing === 'exclusive') {
+			return $existing;
+		} else {
+			return $existing . ' shared locks';
+		}
+	}
 }

+ 7 - 3
lib/public/Lock/LockedException.php

@@ -46,11 +46,15 @@ class LockedException extends \Exception {
 	 *
 	 * @param string $path locked path
 	 * @param \Exception|null $previous previous exception for cascading
-	 *
+	 * @param string $existingLock since 14.0.0
 	 * @since 8.1.0
 	 */
-	public function __construct(string $path, \Exception $previous = null) {
-		parent::__construct('"' . $path . '" is locked', 0, $previous);
+	public function __construct(string $path, \Exception $previous = null, string $existingLock = null) {
+		$message = '"' . $path . '" is locked';
+		if ($existingLock) {
+			$message .= ', existing lock on file: ' . $existingLock;
+		}
+		parent::__construct($message, 0, $previous);
 		$this->path = $path;
 	}