From 0bf717f34fca0e4f3b3c9f077f887aedd8e27606 Mon Sep 17 00:00:00 2001 From: Yurun Date: Fri, 3 Mar 2023 13:04:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Redis=20=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=20delayDestroy=20=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E7=9C=9F=E6=AD=A3=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=20(#475)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConnectionContext/StoreHandler/Redis.php | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/Server/ConnectionContext/StoreHandler/Redis.php b/src/Server/ConnectionContext/StoreHandler/Redis.php index 050afa9b65..5a16c583f7 100644 --- a/src/Server/ConnectionContext/StoreHandler/Redis.php +++ b/src/Server/ConnectionContext/StoreHandler/Redis.php @@ -74,6 +74,16 @@ class Redis implements IHandler */ private int $masterPID = 0; + /** + * 销毁数据的定时器ID. + */ + private ?int $destroyTimerId = null; + + /** + * 要销毁的键名数组. + */ + private array $destroyKeys = []; + public function __init(): void { if ('' === $this->key) @@ -90,6 +100,8 @@ public function __init(): void $this->startPing($redis); }); } + + $this->startDestroyTimer(); } /** @@ -178,6 +190,10 @@ public function __destruct() { Timer::del($this->timerId); } + if (null !== $this->destroyTimerId) + { + Timer::del($this->destroyTimerId); + } } /** @@ -234,9 +250,7 @@ public function destroy(string $key): void */ public function delayDestroy(string $key, int $ttl): void { - $this->useRedis(function (RedisHandler $redis) use ($ttl) { - $redis->expire($this->getStoreKey(), $ttl); - }); + Timer::after($ttl * 1000, fn () => $this->destroyKeys[] = $key); } /** @@ -412,4 +426,21 @@ public function getOldClientIdByFlag(string $flag): ?int { return $this->useRedis(fn (RedisHandler $redis) => $redis->get($this->key . ':binder:old:' . $flag) ?: null); } + + private function startDestroyTimer(): void + { + Timer::tick(1000, function () { + if ($keys = $this->destroyKeys) + { + $this->destroyKeys = []; + $storeKey = $this->getStoreKey(); + $this->useRedis(static function (RedisHandler $redis) use ($keys, $storeKey) { + foreach (array_chunk($keys, 1000) as $keysChunk) + { + $redis->hDel($storeKey, ...$keysChunk); + } + }); + } + }); + } }