From 597d101f0ac30038b8b41d27da6bcfaa1d1c427d Mon Sep 17 00:00:00 2001 From: Esben Petersen Date: Wed, 9 Dec 2020 14:42:21 +0100 Subject: [PATCH] [8.x] Release concurrency lock for errors (#35546) * release concurrency lock for errors * fix style errors * fix style errors --- .../Redis/Limiters/ConcurrencyLimiter.php | 6 ++--- tests/Redis/ConcurrentLimiterTest.php | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Redis/Limiters/ConcurrencyLimiter.php b/src/Illuminate/Redis/Limiters/ConcurrencyLimiter.php index 2dafa6c9e5d4..5fcc921e2c1f 100644 --- a/src/Illuminate/Redis/Limiters/ConcurrencyLimiter.php +++ b/src/Illuminate/Redis/Limiters/ConcurrencyLimiter.php @@ -2,9 +2,9 @@ namespace Illuminate\Redis\Limiters; -use Exception; use Illuminate\Contracts\Redis\LimiterTimeoutException; use Illuminate\Support\Str; +use Throwable; class ConcurrencyLimiter { @@ -61,7 +61,7 @@ public function __construct($redis, $name, $maxLocks, $releaseAfter) * @return bool * * @throws \Illuminate\Contracts\Redis\LimiterTimeoutException - * @throws \Exception + * @throws \Throwable */ public function block($timeout, $callback = null) { @@ -82,7 +82,7 @@ public function block($timeout, $callback = null) return tap($callback(), function () use ($slot, $id) { $this->release($slot, $id); }); - } catch (Exception $exception) { + } catch (Throwable $exception) { $this->release($slot, $id); throw $exception; diff --git a/tests/Redis/ConcurrentLimiterTest.php b/tests/Redis/ConcurrentLimiterTest.php index 78a6792274a5..35e5e64d2ea0 100644 --- a/tests/Redis/ConcurrentLimiterTest.php +++ b/tests/Redis/ConcurrentLimiterTest.php @@ -2,6 +2,7 @@ namespace Illuminate\Tests\Redis; +use Error; use Illuminate\Contracts\Redis\LimiterTimeoutException; use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis; use Illuminate\Redis\Limiters\ConcurrencyLimiter; @@ -140,6 +141,27 @@ public function testItFailsAfterRetryTimeout() $this->assertEquals([1], $store); } + public function testItReleasesIfErrorIsThrown() + { + $store = []; + + $lock = new ConcurrencyLimiter($this->redis(), 'key', 1, 5); + + try { + $lock->block(1, function () { + throw new Error(); + }); + } catch (Error $e) { + } + + $lock = new ConcurrencyLimiter($this->redis(), 'key', 1, 5); + $lock->block(1, function () use (&$store) { + $store[] = 1; + }); + + $this->assertEquals([1], $store); + } + private function redis() { return $this->redis['phpredis']->connection();