diff --git a/src/SequenceResolvers/CacheSequenceResolver.php b/src/SequenceResolvers/CacheSequenceResolver.php index 8b5d676..eff6f41 100644 --- a/src/SequenceResolvers/CacheSequenceResolver.php +++ b/src/SequenceResolvers/CacheSequenceResolver.php @@ -5,8 +5,7 @@ use Glhd\Bits\Contracts\ResolvesSequences; use Illuminate\Cache\RedisStore; use Illuminate\Contracts\Cache\Repository; -use Illuminate\Redis\Connections\PhpRedisConnection; -use Redis; +use Illuminate\Redis\Connections\PredisConnection; class CacheSequenceResolver implements ResolvesSequences { @@ -14,72 +13,40 @@ public function __construct( protected Repository $cache, ) { } - + public function next(int $timestamp): int { $key = "glhd-bits-seq:{$timestamp}"; - - $this->withoutSerializationOrCompression( - fn() => $this->cache->add($key, 0, now()->addSeconds(10)), - ); - + + if ($this->cache->getStore() instanceof RedisStore) { + return $this->redisSafeIncrement($key, ttl: 10); + } + + $this->cache->add($key, 0, now()->addSeconds(10)); + return $this->cache->increment($key) - 1; } - - protected function withoutSerializationOrCompression(callable $callback) + + protected function redisSafeIncrement(string $key, int $ttl): int { - // This is a copied from `RateLimiter::withoutSerializationOrCompression` and - // `PacksPhpRedisValues::withoutSerializationOrCompression` for backwards-compatibility - // reasons (the feature wasn't added until Laravel 11.41.0). - $store = $this->cache->getStore(); - - if (! $store instanceof RedisStore) { - return $callback(); - } - + $key = $store->getPrefix().$key; + + $script = <<connection(); - - if (! $connection instanceof PhpRedisConnection) { - return $callback(); + + if ($connection instanceof PredisConnection) { + return (int) $connection->client()->eval($script, 1, $key, $ttl); } - - $client = $connection->client(); - - $old_serializer = null; - if ($this->serialized($client)) { - $old_serializer = $client->getOption($client::OPT_SERIALIZER); - $client->setOption($client::OPT_SERIALIZER, $client::SERIALIZER_NONE); - } - - $old_compressor = null; - if ($this->compressed($client)) { - $old_compressor = $client->getOption($client::OPT_COMPRESSION); - $client->setOption($client::OPT_COMPRESSION, $client::COMPRESSION_NONE); - } - - try { - return $callback(); - } finally { - if (null !== $old_serializer) { - $client->setOption($client::OPT_SERIALIZER, $old_serializer); - } - - if (null !== $old_compressor) { - $client->setOption($client::OPT_COMPRESSION, $old_compressor); - } - } - } - - public function serialized(Redis $client): bool - { - return defined('Redis::OPT_SERIALIZER') - && $client->getOption(Redis::OPT_SERIALIZER) !== Redis::SERIALIZER_NONE; - } - - public function compressed(Redis $client): bool - { - return defined('Redis::OPT_COMPRESSION') - && $client->getOption(Redis::OPT_COMPRESSION) !== Redis::COMPRESSION_NONE; + + return (int) $connection->client()->eval($script, [$key, $ttl], 1); } }