8000 Add support for postgresql in lock · symfony/symfony@a69a1b7 · GitHub
[go: up one dir, main page]

Skip to content

Commit a69a1b7

Browse files
committed
Add support for postgresql in lock
1 parent 88412a1 commit a69a1b7

File tree

12 files changed

+540
-5
lines changed

12 files changed

+540
-5
lines changed

.github/workflows/tests.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ jobs:
1515
php: ['7.2', '7.4']
1616

1717
services:
18+
postgres:
19+
image: postgres:9.6-alpine
20+
ports:
21+
- 5432:5432
22+
env:
23+
POSTGRES_PASSWORD: 'password'
1824
redis:
1925
image: redis:6.0.0
2026
ports:
@@ -144,6 +150,7 @@ jobs:
144150
MEMCACHED_HOST: localhost
145151
MONGODB_HOST: localhost
146152
KAFKA_BROKER: localhost:9092
153+
POSTGRES_HOST: localhost
147154

148155
- name: Run HTTP push tests
149156
if: matrix.php == '7.4'

src/Symfony/Component/Lock/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ CHANGELOG
99
* added `NoLock`
1010
* deprecated `NotSupportedException`, it shouldn't be thrown anymore.
1111
* deprecated `RetryTillSaveStore`, logic has been moved in `Lock` and is not needed anymore.
12+
* added `InMemoryStore`
13+
* added `PostgreSqlStore`
1214

1315
5.1.0
1416
-----
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
namespace Symfony\Component\Lock\Store;
13+
14+
use Symfony\Component\Lock\Exception\LockConflictedException;
15+
use Symfony\Component\Lock\Key;
16+
use Symfony\Component\Lock\SharedLockStoreInterface;
17+
18+
/**
19+
* InMemoryStore is a PersistingStoreInterface implementation using
20+
* php-array to manage locks.
21+
*
22+
* @author Jérémy Derussé <jeremy@derusse.com>
23+
*/
24+
class InMemoryStore implements SharedLockStoreInterface
25+
{
26+
private $locks = [];
27+
private $readLocks = [];
28+
29+
public function save(Key $key)
30+
{
31+
$hashKey = (string) $key;
32+
$token = $this->getUniqueToken($key);
33+
if (isset($this->locks[$hashKey])) {
34+
// already acquired
35+
if ($this->locks[$hashKey] === $token) {
36+
return;
37+
}
38+
39+
// check for promotion
40+
if (isset($this->readLocks[$hashKey][$token]) && 1 === \count($this->readLocks[$hashKey])) {
41+
unset($this->readLocks[$hashKey]);
42+
$this->locks[$hashKey] = $token;
43+
44+
return;
45+
}
46+
47+
throw new LockConflictedException();
48+
}
49+
50+
$this->locks[$hashKey] = $token;
51+
}
52+
53+
public function saveRead(Key $key)
54+
{
55+
$hashKey = (string) $key;
56+
$token = $this->getUniqueToken($key);
57+
58+
// check if lock is already acquired in read mode
59+
if (isset($this->readLocks[$hashKey])) {
60+
$this->readLocks[$hashKey][$token] = true;
61+
62+
return;
63+
}
64+
65+
if (($this->locks[$hashKey] ?? $token) !== $token) {
66+
throw new LockConflictedException();
67+
}
68+
69+
$this->locks[$hashKey] = 'read';
70+
$this->readLocks[$hashKey][$token] = true;
71+
}
72+
73+
public function putOffExpiration(Key $key, float $ttl)
74+
{
75+
// do nothing, memory locks forever.
76+
}
77+
78+
public function delete(Key $key)
79+
{
80+
$hashKey = (string) $key;
81+
$token = $this->getUniqueToken($key);
82+
83+
unset($this->readLocks[$hashKey][$token]);
84+
if (0 === \count($this->readLocks[$hashKey] ?? [])) {
85+
unset($this->locks[$hashKey]);
86+
}
87+
}
88+
89+
public function exists(Key $key)
90+
{
91+
$hashKey = (string) $key;
92+
$token = $this->getUniqueToken($key);
93+
94+
return isset($this->readLocks[$hashKey][$token]) || ($this->locks[$hashKey] ?? null) === $token;
95+
}
96+
97+
private function getUniqueToken(Key $key): string
98+
{
99+
if (!$key->hasState(__CLASS__)) {
100+
$token = base64_encode(random_bytes(32));
101+
$key->setState(__CLASS__, $token);
102+
}
103+
104+
return $key->getState(__CLASS__);
105+
}
106+
}

src/Symfony/Component/Lock/Store/PdoStore.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ class PdoStore implements PersistingStoreInterface
7474
*
7575
* @throws InvalidArgumentException When first argument is not PDO nor Connection nor string
7676
* @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
77-
* @throws InvalidArgumentException When namespace contains invalid characters
7877
* @throws InvalidArgumentException When the initial ttl is not valid
7978
*/
8079
public function __construct($connOrDsn, array $options = [], float $gcProbability = 0.01, int $initialTtl = 300)

0 commit comments

Comments
 (0)
0