From 69792d8b081d344da32e08ffe37c8b6a99d7ddff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 6 Dec 2024 16:58:51 +0100 Subject: [PATCH 1/6] refactor and fix endianness --- src/mutex/PgAdvisoryLockMutex.php | 18 ++++++++++-------- tests/mutex/PgAdvisoryLockMutexTest.php | 10 +++++++--- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/mutex/PgAdvisoryLockMutex.php b/src/mutex/PgAdvisoryLockMutex.php index 2e210861..403915a2 100644 --- a/src/mutex/PgAdvisoryLockMutex.php +++ b/src/mutex/PgAdvisoryLockMutex.php @@ -9,11 +9,9 @@ class PgAdvisoryLockMutex extends LockMutex /** @var \PDO */ private $pdo; - /** @var int */ - private $key1; + private int $key1; - /** @var int */ - private $key2; + private int $key2; /** * @throws \RuntimeException @@ -22,12 +20,16 @@ public function __construct(\PDO $PDO, string $name) { $this->pdo = $PDO; - $hashed_name = hash('sha256', $name, true); + [$keyBytes1, $keyBytes2] = str_split(hash('sha256', $name, true), 4); - [$bytes1, $bytes2] = str_split($hashed_name, 4); + $unpackToSignedIntFx = static function (string $v) { + $unpacked = unpack('va/Cb/cc', $v); - $this->key1 = unpack('i', $bytes1)[1]; - $this->key2 = unpack('i', $bytes2)[1]; + return ($unpacked['c'] << 24) | ($unpacked['b'] << 16) | $unpacked['a']; + }; + + $this->key1 = $unpackToSignedIntFx($keyBytes1); + $this->key2 = $unpackToSignedIntFx($keyBytes2); } #[\Override] diff --git a/tests/mutex/PgAdvisoryLockMutexTest.php b/tests/mutex/PgAdvisoryLockMutexTest.php index ba933b20..2757e4b8 100644 --- a/tests/mutex/PgAdvisoryLockMutexTest.php +++ b/tests/mutex/PgAdvisoryLockMutexTest.php @@ -52,11 +52,14 @@ public function testAcquireLock(): void } foreach ($arguments as $v) { + self::assertLessThan(1 << 32, $v); + self::assertGreaterThanOrEqual(-(1 << 32), $v); self::assertIsInt($v); } return true; - }) + }), + [-2117040481, 1702710408] )); \Closure::bind(static fn ($mutex) => $mutex->lock(), null, PgAdvisoryLockMutex::class)($this->mutex); @@ -83,12 +86,13 @@ public function testReleaseLock(): void foreach ($arguments as $v) { self::assertLessThan(1 << 32, $v); - self::assertGreaterThan(-(1 << 32), $v); + self::assertGreaterThanOrEqual(-(1 << 32), $v); self::assertIsInt($v); } return true; - }) + }), + [-2117040481, 1702710408] )); \Closure::bind(static fn ($mutex) => $mutex->unlock(), null, PgAdvisoryLockMutex::class)($this->mutex); From 989de1cb642cee99843e7915d05adc98195f55b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 6 Dec 2024 17:00:02 +0100 Subject: [PATCH 2/6] use faster md5 --- src/mutex/PgAdvisoryLockMutex.php | 2 +- tests/mutex/PgAdvisoryLockMutexTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mutex/PgAdvisoryLockMutex.php b/src/mutex/PgAdvisoryLockMutex.php index 403915a2..81ce9f53 100644 --- a/src/mutex/PgAdvisoryLockMutex.php +++ b/src/mutex/PgAdvisoryLockMutex.php @@ -20,7 +20,7 @@ public function __construct(\PDO $PDO, string $name) { $this->pdo = $PDO; - [$keyBytes1, $keyBytes2] = str_split(hash('sha256', $name, true), 4); + [$keyBytes1, $keyBytes2] = str_split(md5($name, true), 4); $unpackToSignedIntFx = static function (string $v) { $unpacked = unpack('va/Cb/cc', $v); diff --git a/tests/mutex/PgAdvisoryLockMutexTest.php b/tests/mutex/PgAdvisoryLockMutexTest.php index 2757e4b8..acf93f31 100644 --- a/tests/mutex/PgAdvisoryLockMutexTest.php +++ b/tests/mutex/PgAdvisoryLockMutexTest.php @@ -59,7 +59,7 @@ public function testAcquireLock(): void return true; }), - [-2117040481, 1702710408] + [-848589047, 1943216454] )); \Closure::bind(static fn ($mutex) => $mutex->lock(), null, PgAdvisoryLockMutex::class)($this->mutex); @@ -92,7 +92,7 @@ public function testReleaseLock(): void return true; }), - [-2117040481, 1702710408] + [-848589047, 1943216454] )); \Closure::bind(static fn ($mutex) => $mutex->unlock(), null, PgAdvisoryLockMutex::class)($this->mutex); From 5c0bd35502384921d4891e91f629d7192658d76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 6 Dec 2024 17:21:53 +0100 Subject: [PATCH 3/6] use prefix for hashing as well for the future --- src/mutex/PgAdvisoryLockMutex.php | 4 +++- tests/mutex/PgAdvisoryLockMutexTest.php | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mutex/PgAdvisoryLockMutex.php b/src/mutex/PgAdvisoryLockMutex.php index 81ce9f53..f950f39d 100644 --- a/src/mutex/PgAdvisoryLockMutex.php +++ b/src/mutex/PgAdvisoryLockMutex.php @@ -4,6 +4,8 @@ namespace malkusch\lock\mutex; +use malkusch\lock\util\LockUtil; + class PgAdvisoryLockMutex extends LockMutex { /** @var \PDO */ @@ -20,7 +22,7 @@ public function __construct(\PDO $PDO, string $name) { $this->pdo = $PDO; - [$keyBytes1, $keyBytes2] = str_split(md5($name, true), 4); + [$keyBytes1, $keyBytes2] = str_split(md5(LockUtil::getInstance()->getKeyPrefix() . ':' . $name, true), 4); $unpackToSignedIntFx = static function (string $v) { $unpacked = unpack('va/Cb/cc', $v); diff --git a/tests/mutex/PgAdvisoryLockMutexTest.php b/tests/mutex/PgAdvisoryLockMutexTest.php index acf93f31..470b0e5e 100644 --- a/tests/mutex/PgAdvisoryLockMutexTest.php +++ b/tests/mutex/PgAdvisoryLockMutexTest.php @@ -59,7 +59,7 @@ public function testAcquireLock(): void return true; }), - [-848589047, 1943216454] + [355884658, 1705446324] )); \Closure::bind(static fn ($mutex) => $mutex->lock(), null, PgAdvisoryLockMutex::class)($this->mutex); @@ -92,7 +92,7 @@ public function testReleaseLock(): void return true; }), - [-848589047, 1943216454] + [355884658, 1705446324] )); \Closure::bind(static fn ($mutex) => $mutex->unlock(), null, PgAdvisoryLockMutex::class)($this->mutex); From 36ac29fc5bc08cdc1a15090857d9d4c78e836e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 6 Dec 2024 21:11:44 +0100 Subject: [PATCH 4/6] improve cs --- src/mutex/PgAdvisoryLockMutex.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mutex/PgAdvisoryLockMutex.php b/src/mutex/PgAdvisoryLockMutex.php index f950f39d..87a2487c 100644 --- a/src/mutex/PgAdvisoryLockMutex.php +++ b/src/mutex/PgAdvisoryLockMutex.php @@ -24,14 +24,15 @@ public function __construct(\PDO $PDO, string $name) [$keyBytes1, $keyBytes2] = str_split(md5(LockUtil::getInstance()->getKeyPrefix() . ':' . $name, true), 4); - $unpackToSignedIntFx = static function (string $v) { + // https://github.com/php/php-src/issues/17068 + $unpackToSignedIntLeFx = static function (string $v) { $unpacked = unpack('va/Cb/cc', $v); - return ($unpacked['c'] << 24) | ($unpacked['b'] << 16) | $unpacked['a']; + return $unpacked['a'] | ($unpacked['b'] << 16) | ($unpacked['c'] << 24); }; - $this->key1 = $unpackToSignedIntFx($keyBytes1); - $this->key2 = $unpackToSignedIntFx($keyBytes2); + $this->key1 = $unpackToSignedIntLeFx($keyBytes1); + $this->key2 = $unpackToSignedIntLeFx($keyBytes2); } #[\Override] From c6d939a8254232c4015189b8c6b3a2fdfa4abf11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 6 Dec 2024 21:15:26 +0100 Subject: [PATCH 5/6] improve test --- tests/mutex/PgAdvisoryLockMutexTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/mutex/PgAdvisoryLockMutexTest.php b/tests/mutex/PgAdvisoryLockMutexTest.php index 470b0e5e..80ed20c1 100644 --- a/tests/mutex/PgAdvisoryLockMutexTest.php +++ b/tests/mutex/PgAdvisoryLockMutexTest.php @@ -24,7 +24,7 @@ protected function setUp(): void $this->pdo = $this->createMock(\PDO::class); - $this->mutex = new PgAdvisoryLockMutex($this->pdo, 'test'); + $this->mutex = new PgAdvisoryLockMutex($this->pdo, 'test-one-negative-key'); } private function isPhpunit9x(): bool @@ -59,7 +59,7 @@ public function testAcquireLock(): void return true; }), - [355884658, 1705446324] + [533558444, -1716795572] )); \Closure::bind(static fn ($mutex) => $mutex->lock(), null, PgAdvisoryLockMutex::class)($this->mutex); @@ -92,7 +92,7 @@ public function testReleaseLock(): void return true; }), - [355884658, 1705446324] + [533558444, -1716795572] )); \Closure::bind(static fn ($mutex) => $mutex->unlock(), null, PgAdvisoryLockMutex::class)($this->mutex); From b56318fdbc44c96418aae7857da21d10ae70b465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 6 Dec 2024 21:26:54 +0100 Subject: [PATCH 6/6] simplify impl --- src/mutex/PgAdvisoryLockMutex.php | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/mutex/PgAdvisoryLockMutex.php b/src/mutex/PgAdvisoryLockMutex.php index 87a2487c..406f7763 100644 --- a/src/mutex/PgAdvisoryLockMutex.php +++ b/src/mutex/PgAdvisoryLockMutex.php @@ -11,9 +11,8 @@ class PgAdvisoryLockMutex extends LockMutex /** @var \PDO */ private $pdo; - private int $key1; - - private int $key2; + /** @var array{int, int} */ + private array $key; /** * @throws \RuntimeException @@ -31,8 +30,10 @@ public function __construct(\PDO $PDO, string $name) return $unpacked['a'] | ($unpacked['b'] << 16) | ($unpacked['c'] << 24); }; - $this->key1 = $unpackToSignedIntLeFx($keyBytes1); - $this->key2 = $unpackToSignedIntLeFx($keyBytes2); + $this->key = [ + $unpackToSignedIntLeFx($keyBytes1), + $unpackToSignedIntLeFx($keyBytes2), + ]; } #[\Override] @@ -40,19 +41,13 @@ protected function lock(): void { $statement = $this->pdo->prepare('SELECT pg_advisory_lock(?, ?)'); - $statement->execute([ - $this->key1, - $this->key2, - ]); + $statement->execute($this->key); } #[\Override] protected function unlock(): void { $statement = $this->pdo->prepare('SELECT pg_advisory_unlock(?, ?)'); - $statement->execute([ - $this->key1, - $this->key2, - ]); + $statement->execute($this->key); } }