RedisSequenceResolver.php 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of the godruoyi/php-snowflake.
  5. *
  6. * (c) Godruoyi <g@godruoyi.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled.
  9. */
  10. namespace Godruoyi\Snowflake;
  11. use Redis;
  12. use RedisException;
  13. class RedisSequenceResolver implements SequenceResolver
  14. {
  15. /**
  16. * The cache prefix.
  17. */
  18. protected string $prefix = '';
  19. /**
  20. * The default redis lua script
  21. */
  22. protected static string $script = <<<'LUA'
  23. if redis.call('set', KEYS[1], ARGV[1], "EX", ARGV[2], "NX") then
  24. return 0
  25. else
  26. return redis.call('incr', KEYS[1])
  27. end
  28. LUA;
  29. /**
  30. * Init resolve instance, must be connected.
  31. *
  32. * @throws RedisException
  33. */
  34. public function __construct(protected Redis $redis)
  35. {
  36. if (! $redis->ping()) {
  37. throw new RedisException('Redis server went away');
  38. }
  39. }
  40. /**
  41. * @throws RedisException
  42. */
  43. public function sequence(int $currentTime): int
  44. {
  45. // 10 seconds
  46. return $this->redis->eval(self::$script, [$this->prefix.$currentTime, '0', '10'], 1) | 0;
  47. }
  48. /**
  49. * Set cache prefix.
  50. */
  51. public function setCachePrefix(string $prefix): self
  52. {
  53. $this->prefix = $prefix;
  54. return $this;
  55. }
  56. }