diff --git a/README.md b/README.md index b0ec6679..cb27b51e 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,7 @@ This library uses the namespace `Malkusch\Lock`. ### Mutex -The [`Malkusch\Lock\Mutex\Mutex`][5] class is an abstract class and provides the -base API for this library. +The [`Malkusch\Lock\Mutex\Mutex`][5] interface provides the base API for this library. #### Mutex::synchronized() @@ -125,9 +124,9 @@ if ($newBalance === false) { } ``` -### Extracting code result after lock release exception +#### Extracting code result after lock release exception -Mutex implementations based on [`Malkush\Lock\Mutex\LockMutex`][10] will throw +Mutex implementations based on [`Malkush\Lock\Mutex\AbstractLockMutex`][10] will throw [`Malkusch\Lock\Exception\LockReleaseException`][11] in case of lock release problem, but the synchronized code block will be already executed at this point. In order to read the code result (or an exception thrown there), @@ -160,9 +159,8 @@ try { ### Implementations -Because the [`Malkusch\Lock\Mutex\Mutex`](#mutex) class is an abstract class, -you can choose from one of the provided implementations or create/extend your -own implementation. +You can choose from one of the provided [`Malkusch\Lock\Mutex\Mutex`](#mutex) interface +implementations or create/extend your own implementation. - [`FlockMutex`](#flockmutex) - [`MemcachedMutex`](#memcachedmutex) @@ -171,7 +169,7 @@ own implementation. - [`SemaphoreMutex`](#semaphoremutex) - [`TransactionalMutex`](#transactionalmutex) - [`MySQLMutex`](#mysqlmutex) -- [`PgAdvisoryLockMutex`](#pgadvisorylockmutex) +- [`PostgreSQLMutex`](#PostgreSQLMutex) #### FlockMutex @@ -342,9 +340,9 @@ $mutex->synchronized(function () use ($bankAccount, $amount) { }); ``` -#### PgAdvisoryLockMutex +#### PostgreSQLMutex -The **PgAdvisoryLockMutex** uses PostgreSQL's +The **PostgreSQLMutex** uses PostgreSQL's [advisory locking](https://www.postgresql.org/docs/9.4/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS) functions. @@ -357,7 +355,7 @@ interrupted, the lock is automatically released. ```php $pdo = new \PDO('pgsql:host=localhost;dbname=test', 'username'); -$mutex = new PgAdvisoryLockMutex($pdo, 'balance'); +$mutex = new PostgreSQLMutex($pdo, 'balance'); $mutex->synchronized(function () use ($bankAccount, $amount) { $balance = $bankAccount->getBalance(); $balance -= $amount; diff --git a/src/Exception/ExecutionOutsideLockException.php b/src/Exception/ExecutionOutsideLockException.php index 5e175adc..f6db422a 100644 --- a/src/Exception/ExecutionOutsideLockException.php +++ b/src/Exception/ExecutionOutsideLockException.php @@ -14,7 +14,7 @@ * * Should only be used in contexts where the is being released. * - * @see \Malkusch\Lock\Mutex\SpinlockMutex::unlock() + * @see \Malkusch\Lock\Mutex\AbstractSpinlockMutex::unlock() */ class ExecutionOutsideLockException extends LockReleaseException { diff --git a/src/Mutex/LockMutex.php b/src/Mutex/AbstractLockMutex.php similarity index 96% rename from src/Mutex/LockMutex.php rename to src/Mutex/AbstractLockMutex.php index cb42c4db..dd7b5f55 100644 --- a/src/Mutex/LockMutex.php +++ b/src/Mutex/AbstractLockMutex.php @@ -12,7 +12,7 @@ * * @internal */ -abstract class LockMutex extends Mutex +abstract class AbstractLockMutex extends AbstractMutex { /** * Acquires the lock. diff --git a/src/Mutex/AbstractMutex.php b/src/Mutex/AbstractMutex.php new file mode 100644 index 00000000..de43eb48 --- /dev/null +++ b/src/Mutex/AbstractMutex.php @@ -0,0 +1,16 @@ +mutex = $this->getMockBuilder(LockMutex::class) + $this->mutex = $this->getMockBuilder(AbstractLockMutex::class) ->onlyMethods(['lock', 'unlock']) ->getMock(); } diff --git a/tests/Mutex/SpinlockMutexTest.php b/tests/Mutex/AbstractSpinlockMutexTest.php similarity index 86% rename from tests/Mutex/SpinlockMutexTest.php rename to tests/Mutex/AbstractSpinlockMutexTest.php index c1ea4c3a..926219e9 100644 --- a/tests/Mutex/SpinlockMutexTest.php +++ b/tests/Mutex/AbstractSpinlockMutexTest.php @@ -8,14 +8,14 @@ use Malkusch\Lock\Exception\LockAcquireException; use Malkusch\Lock\Exception\LockReleaseException; use Malkusch\Lock\Exception\TimeoutException; -use Malkusch\Lock\Mutex\SpinlockMutex; +use Malkusch\Lock\Mutex\AbstractSpinlockMutex; use phpmock\environment\SleepEnvironmentBuilder; use phpmock\MockEnabledException; use phpmock\phpunit\PHPMock; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -class SpinlockMutexTest extends TestCase +class AbstractSpinlockMutexTest extends TestCase { use PHPMock; @@ -39,11 +39,11 @@ protected function setUp(): void } /** - * @return SpinlockMutex&MockObject + * @return AbstractSpinlockMutex&MockObject */ - private function createSpinlockMutexMock(float $timeout = 3): SpinlockMutex + private function createAbstractSpinlockMutexMock(float $timeout = 3): AbstractSpinlockMutex { - return $this->getMockBuilder(SpinlockMutex::class) + return $this->getMockBuilder(AbstractSpinlockMutex::class) ->setConstructorArgs(['test', $timeout]) ->onlyMethods(['acquire', 'release']) ->getMock(); @@ -56,7 +56,7 @@ public function testFailAcquireLock(): void { $this->expectException(LockAcquireException::class); - $mutex = $this->createSpinlockMutexMock(); + $mutex = $this->createAbstractSpinlockMutexMock(); $mutex->expects(self::any()) ->method('acquire') ->willThrowException(new LockAcquireException()); @@ -74,7 +74,7 @@ public function testAcquireTimesOut(): void $this->expectException(TimeoutException::class); $this->expectExceptionMessage('Timeout of 3.0 seconds exceeded'); - $mutex = $this->createSpinlockMutexMock(); + $mutex = $this->createAbstractSpinlockMutexMock(); $mutex->expects(self::atLeastOnce()) ->method('acquire') ->willReturn(false); @@ -89,7 +89,7 @@ public function testAcquireTimesOut(): void */ public function testExecuteTooLong(): void { - $mutex = $this->createSpinlockMutexMock(0.5); + $mutex = $this->createAbstractSpinlockMutexMock(0.5); $mutex->expects(self::any()) ->method('acquire') ->willReturn(true); @@ -114,7 +114,7 @@ public function testExecuteTooLong(): void */ public function testExecuteBarelySucceeds(): void { - $mutex = $this->createSpinlockMutexMock(0.5); + $mutex = $this->createAbstractSpinlockMutexMock(0.5); $mutex->expects(self::any())->method('acquire')->willReturn(true); $mutex->expects(self::once())->method('release')->willReturn(true); @@ -130,7 +130,7 @@ public function testFailReleasingLock(): void { $this->expectException(LockReleaseException::class); - $mutex = $this->createSpinlockMutexMock(); + $mutex = $this->createAbstractSpinlockMutexMock(); $mutex->expects(self::any())->method('acquire')->willReturn(true); $mutex->expects(self::any())->method('release')->willReturn(false); @@ -142,7 +142,7 @@ public function testFailReleasingLock(): void */ public function testExecuteTimeoutLeavesOneSecondForKeyToExpire(): void { - $mutex = $this->createSpinlockMutexMock(0.2); + $mutex = $this->createAbstractSpinlockMutexMock(0.2); $mutex->expects(self::once()) ->method('acquire') ->with(self::anything(), 1.2) diff --git a/tests/Mutex/MutexConcurrencyTest.php b/tests/Mutex/MutexConcurrencyTest.php index 8c4b112c..970ea195 100644 --- a/tests/Mutex/MutexConcurrencyTest.php +++ b/tests/Mutex/MutexConcurrencyTest.php @@ -9,8 +9,8 @@ use Malkusch\Lock\Mutex\MemcachedMutex; use Malkusch\Lock\Mutex\Mutex; use Malkusch\Lock\Mutex\MySQLMutex; -use Malkusch\Lock\Mutex\PgAdvisoryLockMutex; use Malkusch\Lock\Mutex\PHPRedisMutex; +use Malkusch\Lock\Mutex\PostgreSQLMutex; use Malkusch\Lock\Mutex\PredisMutex; use Malkusch\Lock\Mutex\SemaphoreMutex; use Malkusch\Lock\Mutex\TransactionalMutex; @@ -325,11 +325,11 @@ static function (string $uri): \Redis { } if (getenv('PGSQL_DSN')) { - yield 'PgAdvisoryLockMutex' => [static function (): Mutex { + yield 'PostgreSQLMutex' => [static function (): Mutex { $pdo = new \PDO(getenv('PGSQL_DSN'), getenv('PGSQL_USER'), getenv('PGSQL_PASSWORD')); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - return new PgAdvisoryLockMutex($pdo, 'test'); + return new PostgreSQLMutex($pdo, 'test'); }]; } } diff --git a/tests/Mutex/MutexTest.php b/tests/Mutex/MutexTest.php index 8c7db20b..58dd6b93 100644 --- a/tests/Mutex/MutexTest.php +++ b/tests/Mutex/MutexTest.php @@ -5,17 +5,17 @@ namespace Malkusch\Lock\Tests\Mutex; use Eloquent\Liberator\Liberator; +use Malkusch\Lock\Mutex\AbstractLockMutex; +use Malkusch\Lock\Mutex\AbstractSpinlockMutex; use Malkusch\Lock\Mutex\FlockMutex; -use Malkusch\Lock\Mutex\LockMutex; use Malkusch\Lock\Mutex\MemcachedMutex; use Malkusch\Lock\Mutex\Mutex; use Malkusch\Lock\Mutex\MySQLMutex; use Malkusch\Lock\Mutex\NoMutex; -use Malkusch\Lock\Mutex\PgAdvisoryLockMutex; use Malkusch\Lock\Mutex\PHPRedisMutex; +use Malkusch\Lock\Mutex\PostgreSQLMutex; use Malkusch\Lock\Mutex\PredisMutex; use Malkusch\Lock\Mutex\SemaphoreMutex; -use Malkusch\Lock\Mutex\SpinlockMutex; use Malkusch\Lock\Mutex\TransactionalMutex; use org\bovigo\vfs\vfsStream; use PHPUnit\Framework\Attributes\DataProvider; @@ -87,8 +87,8 @@ public static function provideMutexFactoriesCases(): iterable }]; } - yield 'SpinlockMutex' => [static function (): Mutex { - $lock = new class('test') extends SpinlockMutex { + yield 'AbstractSpinlockMutex' => [static function (): Mutex { + $lock = new class('test') extends AbstractSpinlockMutex { #[\Override] protected function acquire(string $key, float $expire): bool { @@ -105,8 +105,8 @@ protected function release(string $key): bool return $lock; }]; - yield 'LockMutex' => [static function (): Mutex { - $lock = new class extends LockMutex { + yield 'AbstractLockMutex' => [static function (): Mutex { + $lock = new class extends AbstractLockMutex { #[\Override] protected function lock(): void {} @@ -176,11 +176,11 @@ static function ($uri) { } if (getenv('PGSQL_DSN')) { - yield 'PgAdvisoryLockMutex' => [static function (): Mutex { + yield 'PostgreSQLMutex' => [static function (): Mutex { $pdo = new \PDO(getenv('PGSQL_DSN'), getenv('PGSQL_USER'), getenv('PGSQL_PASSWORD')); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - return new PgAdvisoryLockMutex($pdo, 'test'); + return new PostgreSQLMutex($pdo, 'test'); }]; } } diff --git a/tests/Mutex/PgAdvisoryLockMutexTest.php b/tests/Mutex/PostgreSQLMutexTest.php similarity index 90% rename from tests/Mutex/PgAdvisoryLockMutexTest.php rename to tests/Mutex/PostgreSQLMutexTest.php index 8ed704d6..2ebd43a0 100644 --- a/tests/Mutex/PgAdvisoryLockMutexTest.php +++ b/tests/Mutex/PostgreSQLMutexTest.php @@ -4,17 +4,17 @@ namespace Malkusch\Lock\Tests\Mutex; -use Malkusch\Lock\Mutex\PgAdvisoryLockMutex; +use Malkusch\Lock\Mutex\PostgreSQLMutex; use PHPUnit\Framework\Constraint\IsType; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -class PgAdvisoryLockMutexTest extends TestCase +class PostgreSQLMutexTest extends TestCase { /** @var \PDO&MockObject */ private $pdo; - /** @var PgAdvisoryLockMutex */ + /** @var PostgreSQLMutex */ private $mutex; #[\Override] @@ -24,7 +24,7 @@ protected function setUp(): void $this->pdo = $this->createMock(\PDO::class); - $this->mutex = new PgAdvisoryLockMutex($this->pdo, 'test-one-negative-key'); + $this->mutex = new PostgreSQLMutex($this->pdo, 'test-one-negative-key'); } private function isPhpunit9x(): bool @@ -62,7 +62,7 @@ public function testAcquireLock(): void [533558444, -1716795572] )); - \Closure::bind(static fn ($mutex) => $mutex->lock(), null, PgAdvisoryLockMutex::class)($this->mutex); + \Closure::bind(static fn ($mutex) => $mutex->lock(), null, PostgreSQLMutex::class)($this->mutex); } public function testReleaseLock(): void @@ -95,6 +95,6 @@ public function testReleaseLock(): void [533558444, -1716795572] )); - \Closure::bind(static fn ($mutex) => $mutex->unlock(), null, PgAdvisoryLockMutex::class)($this->mutex); + \Closure::bind(static fn ($mutex) => $mutex->unlock(), null, PostgreSQLMutex::class)($this->mutex); } }