11** [ Requirements] ( #requirements ) ** |
22** [ Installation] ( #installation ) ** |
33** [ Usage] ( #usage ) ** |
4+ ** [ Implementations] ( #implementations ) ** |
45** [ Authors] ( #authors ) ** |
56** [ License] ( #license ) **
67
@@ -51,7 +52,7 @@ This library uses the namespace `Malkusch\Lock`.
5152
5253The [ ` Malkusch\Lock\Mutex\Mutex ` ] [ 5 ] interface provides the base API for this library.
5354
54- #### Mutex::synchronized()
55+ ### Mutex::synchronized()
5556
5657[ ` Malkusch\Lock\Mutex\Mutex::synchronized() ` ] [ 6 ] executes code exclusively. This
5758method guarantees that the code is only executed by one process at once. Other
@@ -65,10 +66,7 @@ return value `false` or `null` should be seen as a failed action.
6566Example:
6667
6768``` php
68- $newBalance = $mutex->synchronized(function () use (
69- $bankAccount,
70- $amount
71- ): int {
69+ $newBalance = $mutex->synchronized(static function () use ($bankAccount, $amount) {
7270 $balance = $bankAccount->getBalance();
7371 $balance -= $amount;
7472 if ($balance < 0) {
@@ -80,7 +78,7 @@ $newBalance = $mutex->synchronized(function () use (
8078});
8179```
8280
83- #### Mutex::check()
81+ ### Mutex::check()
8482
8583[ ` Malkusch\Lock\Mutex\Mutex::check() ` ] [ 7 ] sets a callable, which will be
8684executed when [ ` Malkusch\Lock\Util\DoubleCheckedLocking::then() ` ] [ 8 ] is called,
@@ -108,24 +106,24 @@ this return value will not be checked by the library.
108106Example:
109107
110108``` php
111- $newBalance = $mutex->check(function () use ($bankAccount, $amount): bool {
109+ $newBalance = $mutex->check(static function () use ($bankAccount, $amount): bool {
112110 return $bankAccount->getBalance() >= $amount;
113- })->then(function () use ($bankAccount, $amount): int {
111+ })->then(static function () use ($bankAccount, $amount) {
114112 $balance = $bankAccount->getBalance();
115113 $balance -= $amount;
116114 $bankAccount->setBalance($balance);
117115
118116 return $balance;
119117});
120118
121- if ($newBalance === false ) {
119+ if (! $newBalance) {
122120 if ($balance < 0) {
123121 throw new \DomainException('You have no credit');
124122 }
125123}
126124```
127125
128- #### Extracting code result after lock release exception
126+ ### Extracting code result after lock release exception
129127
130128Mutex implementations based on [ ` Malkush\Lock\Mutex\AbstractLockMutex ` ] [ 10 ] will throw
131129[ ` Malkusch\Lock\Exception\LockReleaseException ` ] [ 11 ] in case of lock release
@@ -136,8 +134,8 @@ In order to read the code result (or an exception thrown there),
136134Example:
137135``` php
138136try {
139- // or $mutex->check(...)
140- $result = $mutex->synchronized(function () {
137+ // OR $mutex->check(...)
138+ $result = $mutex->synchronized(static function () {
141139 if (someCondition()) {
142140 throw new \DomainException();
143141 }
@@ -149,7 +147,7 @@ try {
149147 $codeException = $unlockException->getCodeException();
150148 // do something with the code exception
151149 } else {
152- $code_result = $unlockException->getCodeResult();
150+ $codeResult = $unlockException->getCodeResult();
153151 // do something with the code result
154152 }
155153
@@ -158,7 +156,7 @@ try {
158156}
159157```
160158
161- ### Implementations
159+ ## Implementations
162160
163161You can choose from one of the provided [ ` Malkusch\Lock\Mutex\Mutex ` ] ( #mutex ) interface
164162implementations or create/extend your own implementation.
@@ -168,30 +166,23 @@ implementations or create/extend your own implementation.
168166- [ ` RedisMutex ` ] ( #redismutex )
169167- [ ` SemaphoreMutex ` ] ( #semaphoremutex )
170168- [ ` MySQLMutex ` ] ( #mysqlmutex )
171- - [ ` PostgreSQLMutex ` ] ( #PostgreSQLMutex )
169+ - [ ` PostgreSQLMutex ` ] ( #postgresqlmutex )
170+ - [ ` DistributedMutex ` ] ( #distributedmutex )
172171
173- #### FlockMutex
172+ ### FlockMutex
174173
175174The ** FlockMutex** is a lock implementation based on
176175[ ` flock() ` ] ( https://php.net/manual/en/function.flock.php ) .
177176
178177Example:
179178``` php
180179$mutex = new FlockMutex(fopen(__FILE__, 'r'));
181- $mutex->synchronized(function () use ($bankAccount, $amount) {
182- $balance = $bankAccount->getBalance();
183- $balance -= $amount;
184- if ($balance < 0) {
185- throw new \DomainException('You have no credit');
186- }
187- $bankAccount->setBalance($balance);
188- });
189180```
190181
191182Timeouts are supported as an optional second argument. This uses the ` ext-pcntl `
192183extension if possible or busy waiting if not.
193184
194- #### MemcachedMutex
185+ ### MemcachedMutex
195186
196187The ** MemcachedMutex** is a spinlock implementation which uses the
197188[ ` Memcached ` extension] ( https://php.net/manual/en/book.memcached.php ) .
@@ -202,22 +193,13 @@ $memcached = new \Memcached();
202193$memcached->addServer('localhost', 11211);
203194
204195$mutex = new MemcachedMutex('balance', $memcached);
205- $mutex->synchronized(function () use ($bankAccount, $amount) {
206- $balance = $bankAccount->getBalance();
207- $balance -= $amount;
208- if ($balance < 0) {
209- throw new \DomainException('You have no credit');
210- }
211- $bankAccount->setBalance($balance);
212- });
213196```
214197
215- #### RedisMutex
198+ ### RedisMutex
216199
217- The ** RedisMutex** is the distributed lock implementation of
218- [ RedLock] ( https://redis.io/topics/distlock#the-redlock-algorithm ) which supports the
200+ The ** RedisMutex** is a lock implementation which supports the
219201[ ` phpredis ` extension] ( https://github.com/phpredis/phpredis )
220- or [ ` Predis ` API] ( https://github.com/nrk/predis ) .
202+ or [ ` Predis ` API] ( https://github.com/nrk/predis ) clients .
221203
222204Both Redis and Valkey servers are supported.
223205
@@ -230,18 +212,10 @@ $redis = new \Redis();
230212$redis->connect('localhost');
231213// OR $redis = new \Predis\Client('redis://localhost');
232214
233- $mutex = new RedisMutex([$redis], 'balance');
234- $mutex->synchronized(function () use ($bankAccount, $amount) {
235- $balance = $bankAccount->getBalance();
236- $balance -= $amount;
237- if ($balance < 0) {
238- throw new \DomainException('You have no credit');
239- }
240- $bankAccount->setBalance($balance);
241- });
215+ $mutex = new RedisMutex($redis, 'balance');
242216```
243217
244- #### SemaphoreMutex
218+ ### SemaphoreMutex
245219
246220The ** SemaphoreMutex** is a lock implementation based on
247221[ Semaphore] ( https://php.net/manual/en/ref.sem.php ) .
@@ -250,17 +224,9 @@ Example:
250224``` php
251225$semaphore = sem_get(ftok(__FILE__, 'a'));
252226$mutex = new SemaphoreMutex($semaphore);
253- $mutex->synchronized(function () use ($bankAccount, $amount) {
254- $balance = $bankAccount->getBalance();
255- $balance -= $amount;
256- if ($balance < 0) {
257- throw new \DomainException('You have no credit');
258- }
259- $bankAccount->setBalance($balance);
260- });
261227```
262228
263- #### MySQLMutex
229+ ### MySQLMutex
264230
265231The ** MySQLMutex** uses MySQL's
266232[ ` GET_LOCK ` ] ( https://dev.mysql.com/doc/refman/9.0/en/locking-functions.html#function_get-lock )
@@ -280,19 +246,10 @@ you to namespace your locks like `dbname.lockname`.
280246
281247``` php
282248$pdo = new \PDO('mysql:host=localhost;dbname=test', 'username');
283-
284249$mutex = new MySQLMutex($pdo, 'balance', 15);
285- $mutex->synchronized(function () use ($bankAccount, $amount) {
286- $balance = $bankAccount->getBalance();
287- $balance -= $amount;
288- if ($balance < 0) {
289- throw new \DomainException('You have no credit');
290- }
291- $bankAccount->setBalance($balance);
292- });
293250```
294251
295- #### PostgreSQLMutex
252+ ### PostgreSQLMutex
296253
297254The ** PostgreSQLMutex** uses PostgreSQL's
298255[ advisory locking] ( https://www.postgresql.org/docs/9.4/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS )
@@ -306,16 +263,21 @@ interrupted, the lock is automatically released.
306263
307264``` php
308265$pdo = new \PDO('pgsql:host=localhost;dbname=test', 'username');
309-
310266$mutex = new PostgreSQLMutex($pdo, 'balance');
311- $mutex->synchronized(function () use ($bankAccount, $amount) {
312- $balance = $bankAccount->getBalance();
313- $balance -= $amount;
314- if ($balance < 0) {
315- throw new \DomainException('You have no credit');
316- }
317- $bankAccount->setBalance($balance);
318- });
267+ ```
268+
269+ ### DistributedMutex
270+
271+ The ** DistributedMutex** is the distributed lock implementation of
272+ [ RedLock] ( https://redis.io/topics/distlock#the-redlock-algorithm ) which supports
273+ one or more [ ` Malkush\Lock\Mutex\AbstractSpinlockMutex ` ] [ 10 ] instances.
274+
275+ Example:
276+ ``` php
277+ $mutex = new DistributedMutex([
278+ new \Predis\Client('redis://10.0.0.1'),
279+ new \Predis\Client('redis://10.0.0.2'),
280+ ], 'balance');
319281```
320282
321283## Authors
@@ -341,3 +303,4 @@ This project is free and is licensed under the MIT.
341303[ 9 ] : https://en.wikipedia.org/wiki/Double-checked_locking
342304[ 10 ] : https://github.com/php-lock/lock/blob/3ca295ccda/src/Mutex/AbstractLockMutex.php
343305[ 11 ] : https://github.com/php-lock/lock/blob/3ca295ccda/src/Exception/LockReleaseException.php
306+ [ 12 ] : https://github.com/php-lock/lock/blob/41509dda0a/src/Mutex/AbstractSpinlockMutex.php#L15
0 commit comments