Skip to content

Commit 35ec747

Browse files
committed
Rewrite locker API
1 parent 43ac0ce commit 35ec747

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
/*
4+
* This file is part of PHP DB Locker.
5+
*
6+
* (c) Anton Komarev <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Cog\DbLocker\Locker;
15+
16+
use Cog\DbLocker\LockId\PostgresLockId;
17+
use PDO;
18+
19+
final class AdvisoryLockSessionLevel
20+
{
21+
private bool $isReleased = false;
22+
23+
public function __construct(
24+
private readonly PDO $dbConnection,
25+
private readonly PostgresAdvisoryLocker $locker,
26+
public readonly PostgresLockId $lockId,
27+
public readonly PostgresLockAccessModeEnum $accessMode,
28+
public readonly bool $wasAcquired,
29+
) {}
30+
31+
/**
32+
* Explicitly release the lock if it was acquired and not yet released.
33+
*
34+
* @return bool True if the lock was released, false if it wasn't acquired or already released
35+
*/
36+
public function release(): bool
37+
{
38+
/**
39+
* This code is mimicking the behavior of DB lock release.
40+
*/
41+
if (!$this->wasAcquired || $this->isReleased) {
42+
return false;
43+
}
44+
45+
$wasReleased = $this->locker->releaseSessionLevelLock(
46+
$this->dbConnection,
47+
$this->lockId,
48+
);
49+
50+
if ($wasReleased) {
51+
$this->isReleased = true;
52+
}
53+
54+
return $wasReleased;
55+
}
56+
57+
/**
58+
* Automatically release the lock when the handle is destroyed.
59+
*/
60+
public function __destruct()
61+
{
62+
// TODO: Do we need to
63+
$this->release();
64+
}
65+
}

src/Locker/PostgresAdvisoryLocker.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,34 @@ public function acquireTransactionLevelLock(
3838
}
3939

4040
/**
41-
* Acquire a session-level advisory lock with a configurable acquisition type and mode.
41+
* Acquire a session-level advisory lock with a configurable wait & access modes.
42+
*
43+
* TODO: Write that transaction-level is recommended.
44+
* TODO: Cover with tests
45+
*/
46+
public function acquireSessionLevelLockHandler(
47+
PDO $dbConnection,
48+
PostgresLockId $postgresLockId,
49+
PostgresAdvisoryLockWaitModeEnum $waitMode = PostgresAdvisoryLockWaitModeEnum::NonBlocking,
50+
PostgresLockAccessModeEnum $accessMode = PostgresLockAccessModeEnum::Exclusive,
51+
): AdvisoryLockSessionLevel {
52+
return new AdvisoryLockSessionLevel(
53+
$dbConnection,
54+
$this,
55+
$postgresLockId,
56+
$accessMode,
57+
wasAcquired: $this->acquireLock(
58+
$dbConnection,
59+
$postgresLockId,
60+
PostgresAdvisoryLockLevelEnum::Session,
61+
$waitMode,
62+
$accessMode,
63+
),
64+
);
65+
}
66+
67+
/**
68+
* Acquire a session-level advisory lock with a configurable wait & access modes.
4269
*
4370
* TODO: Write that transaction-level is recommended.
4471
*/

0 commit comments

Comments
 (0)