Redis.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <?php
  2. /**
  3. * This file is part of webman.
  4. *
  5. * Licensed under The MIT License
  6. * For full copyright and license information, please see the MIT-LICENSE.txt
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @author walkor<walkor@workerman.net>
  10. * @copyright walkor<walkor@workerman.net>
  11. * @link http://www.workerman.net/
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Webman\RedisQueue;
  15. use RedisException;
  16. use Webman\Context;
  17. use Workerman\Coroutine\Pool;
  18. /**
  19. * Class RedisQueue
  20. * @package support
  21. *
  22. * Strings methods
  23. * @method static bool send($queue, $data, $delay=0)
  24. */
  25. class Redis
  26. {
  27. /**
  28. * @var Pool[]
  29. */
  30. protected static array $pools = [];
  31. /**
  32. * @param string $name
  33. * @return RedisConnection
  34. */
  35. public static function connection($name = 'default') {
  36. $name = $name ?: 'default';
  37. $key = "redis-queue.connections.$name";
  38. $connection = Context::get($key);
  39. if (!$connection) {
  40. if (!isset(static::$pools[$name])) {
  41. $configs = config('redis_queue', config('plugin.webman.redis-queue.redis', []));
  42. if (!isset($configs[$name])) {
  43. throw new \RuntimeException("RedisQueue connection $name not found");
  44. }
  45. $config = $configs[$name];
  46. $pool = new Pool($config['pool']['max_connections'] ?? 10, $config['pool'] ?? []);
  47. $pool->setConnectionCreator(function () use ($config) {
  48. return static::connect($config);
  49. });
  50. $pool->setConnectionCloser(function ($connection) {
  51. $connection->close();
  52. });
  53. $pool->setHeartbeatChecker(function ($connection) {
  54. return $connection->ping();
  55. });
  56. static::$pools[$name] = $pool;
  57. }
  58. try {
  59. $connection = static::$pools[$name]->get();
  60. Context::set($key, $connection);
  61. } finally {
  62. Context::onDestroy(function () use ($connection, $name) {
  63. try {
  64. $connection && static::$pools[$name]->put($connection);
  65. } catch (Throwable) {
  66. // ignore
  67. }
  68. });
  69. }
  70. }
  71. return $connection;
  72. }
  73. /**
  74. * Connect to redis.
  75. *
  76. * @param $config
  77. * @return RedisConnection
  78. * @throws RedisException
  79. */
  80. protected static function connect($config): RedisConnection
  81. {
  82. if (!extension_loaded('redis')) {
  83. throw new \RuntimeException('Please make sure the PHP Redis extension is installed and enabled.');
  84. }
  85. $redis = new RedisConnection();
  86. $address = $config['host'];
  87. $config = [
  88. 'host' => str_starts_with($address, 'unix:///') ? $address : parse_url($address, PHP_URL_HOST),
  89. 'port' => parse_url($address, PHP_URL_PORT),
  90. 'db' => $config['options']['database'] ?? $config['options']['db'] ?? 0,
  91. 'auth' => $config['options']['auth'] ?? '',
  92. 'timeout' => $config['options']['timeout'] ?? 2,
  93. 'ping' => $config['options']['ping'] ?? 55,
  94. 'prefix' => $config['options']['prefix'] ?? '',
  95. ];
  96. $redis->connectWithConfig($config);
  97. return $redis;
  98. }
  99. /**
  100. * @param $name
  101. * @param $arguments
  102. * @return mixed
  103. */
  104. public static function __callStatic($name, $arguments)
  105. {
  106. return static::connection('default')->{$name}(... $arguments);
  107. }
  108. }