diff --git a/src/redis/publish/redis.php b/src/redis/publish/redis.php index c5d140318..82869ff16 100644 --- a/src/redis/publish/redis.php +++ b/src/redis/publish/redis.php @@ -13,7 +13,7 @@ declare(strict_types=1); return [ 'default' => [ 'host' => env('REDIS_HOST', 'localhost'), - 'auth' => env('REDIS_AUTH', ''), + 'auth' => env('REDIS_AUTH', null), 'port' => (int) env('REDIS_PORT', 6379), 'db' => (int) env('REDIS_DB', 0), 'timeout' => 0.0, diff --git a/src/redis/src/Redis.php b/src/redis/src/Redis.php index 8c34a6698..bff99cf57 100644 --- a/src/redis/src/Redis.php +++ b/src/redis/src/Redis.php @@ -45,8 +45,8 @@ class Redis // Release connection. if (! $hasContextConnection) { if ($this->shouldUseSameConnection($name)) { - if ($name == 'select') { - $connection->setDbChanged(true); + if ($name == 'select' && $db = $arguments[0] ?? null) { + $connection->setDatabase((int) $db); } // Should storage the connection to coroutine context, then use defer() to release the connection. Context::set($this->getContextKey(), $connection); diff --git a/src/redis/src/RedisConnection.php b/src/redis/src/RedisConnection.php index 425587fee..910089dbd 100644 --- a/src/redis/src/RedisConnection.php +++ b/src/redis/src/RedisConnection.php @@ -28,17 +28,29 @@ class RedisConnection extends BaseConnection implements ConnectionInterface /** * @var array */ - protected $config; + protected $config = [ + 'host' => 'localhost', + 'port' => 6379, + 'auth' => null, + 'db' => 0, + 'timeout' => 0.0, + ]; /** * @var bool */ protected $dbChanged = false; + /** + * Current database. + * @var int + */ + protected $database; + public function __construct(ContainerInterface $container, Pool $pool, array $config) { parent::__construct($container, $pool); - $this->config = $config; + $this->config = array_replace($this->config, $config); $this->reconnect(); } @@ -63,11 +75,11 @@ class RedisConnection extends BaseConnection implements ConnectionInterface public function reconnect(): bool { - $host = $this->config['host'] ?? 'localhost'; - $port = $this->config['port'] ?? 6379; - $auth = $this->config['auth'] ?? null; - $db = $this->config['db'] ?? 0; - $timeout = $this->config['timeout'] ?? 0.0; + $host = $this->config['host']; + $port = $this->config['port']; + $auth = $this->config['auth']; + $db = $this->config['db']; + $timeout = $this->config['timeout']; $redis = new \Redis(); if (! $redis->connect($host, $port, $timeout)) { @@ -78,13 +90,13 @@ class RedisConnection extends BaseConnection implements ConnectionInterface $redis->auth($auth); } - if ($db > 0) { - $redis->select($db); + $database = $this->database ?? $db; + if ($database > 0) { + $redis->select($database); } $this->connection = $redis; $this->lastUseTime = microtime(true); - $this->setDbChanged(false); return true; } @@ -96,19 +108,16 @@ class RedisConnection extends BaseConnection implements ConnectionInterface public function release(): void { - if ($this->dbChanged) { + if ($this->database && $this->database != $this->config['db']) { // Select the origin db after execute select. - $this->select($this->config['db'] ?? 0); - $this->setDbChanged(false); + $this->select($this->config['db']); + $this->database = null; } parent::release(); } - /** - * @param bool $dbChanged - */ - public function setDbChanged(bool $dbChanged): void + public function setDatabase(int $database): void { - $this->dbChanged = $dbChanged; + $this->database = $database; } } diff --git a/src/redis/tests/RedisTest.php b/src/redis/tests/RedisTest.php index 3ae47c0a6..54577edd1 100644 --- a/src/redis/tests/RedisTest.php +++ b/src/redis/tests/RedisTest.php @@ -48,22 +48,9 @@ class RedisTest extends TestCase $this->assertTrue($redis->connect('127.0.0.1', 6379, 0.0)); } - public function testRedisCommand() + public function testRedisSelect() { - $container = Mockery::mock(Container::class); - $container->shouldReceive('get')->once()->with(ConfigInterface::class)->andReturn(new Config([ - 'redis' => [ - 'default' => [], - ], - ])); - $pool = new RedisPoolStub($container, 'default'); - $container->shouldReceive('make')->once()->with(RedisPool::class, ['name' => 'default'])->andReturn($pool); - - ApplicationContext::setContainer($container); - - $factory = new PoolFactory($container); - - $redis = new Redis($factory); + $redis = $this->getRedis(); $res = $redis->set('xxxx', 'yyyy'); $this->assertSame('db:0 name:set argument:xxxx,yyyy', $res); @@ -77,4 +64,35 @@ class RedisTest extends TestCase $this->assertSame('db:0 name:get argument:xxxx', $res); }]); } + + private function getRedis() + { + $container = Mockery::mock(Container::class); + $container->shouldReceive('get')->once()->with(ConfigInterface::class)->andReturn(new Config([ + 'redis' => [ + 'default' => [ + 'host' => 'localhost', + 'auth' => null, + 'port' => 6379, + 'db' => 0, + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 30, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + 'max_idle_time' => 1, + ], + ], + ], + ])); + $pool = new RedisPoolStub($container, 'default'); + $container->shouldReceive('make')->once()->with(RedisPool::class, ['name' => 'default'])->andReturn($pool); + + ApplicationContext::setContainer($container); + + $factory = new PoolFactory($container); + + return new Redis($factory); + } }