Predis协程问题[已解决]

ichynul

问题描述

自己写的redislock,支持redis和predis。
由于很多老项目是php7.4,目前的php8没有安装redis扩展,所以使用composer安装的predis.
但运行中偶尔报错,好像是协程支持的问题

/vendor/predis/predis/src/Connection/Resource/Stream.php on line 249
PHP Fatal error:  Uncaught Swoole\Error: Socket#13 has already been bound to another coroutine#1381, reading of the same socket in coroutine#1383 at the same time is not allowed in /vendor/predis/predis/src/Connection/Resource/Stream.php:249
Stack trace:
#0 /vendor/predis/predis/src/Connection/Resource/Stream.php(249): fgets()
#1 /vendor/predis/predis/src/Connection/StreamConnection.php(150): Predis\Connection\Resource\Stream->read()
#2 /vendor/predis/predis/src/Connection/AbstractConnection.php(144): Predis\Connection\StreamConnection->read()
#3 /vendor/predis/predis/src/Connection/AbstractConnection.php(136): Predis\Connection\AbstractConnection->readResponse()
#4 /vendor/predis/predis/src/Client.php(382): Predis\Connection\AbstractConnection->executeCommand()
#5 /vendor/predis/predis/src/Client.php(336): Predis\Client->executeCommand()
#6 /app/common/logic/RedisLockLogic.php(237): Predis\Client->__call()

连接池:

/**
     * 创建驱动
     *
     * @return mixed
     *
     * @throws \Throwable
     */
    protected function createDriver(): mixed
    {
        $key = "__redis_lock__";
        $connection = Context::get($key);
        if (!$connection) {
            if (!static::$pool) {
                static::$pool = new Pool($this->poolConfig['max_connections'] ?? 10, $this->poolConfig);
                static::$pool->setConnectionCreator(function () {
                    return $this->make();//创建redis 或 predis
                });
                static::$pool->setConnectionCloser(function ($connection) {
                    if (method_exists($connection, 'close')) {
                        $connection->close();
                    } else {
                        $connection->quit();
                    }
                });
                static::$pool->setHeartbeatChecker(function ($connection) {
                    $connection->get('PING');
                });
            }
            try {
                $connection = static::$pool->get();
                Context::set($key, $connection);
            } finally {
                Context::onDestroy(function () use ($connection) {
                    try {
                        $connection && static::$pool->put($connection);
                    } catch (\Throwable $e) {
                        // ignore
                    }
                });
            }
        }

        return $connection;
    }

为此你搜索到了哪些方案及不适用的原因

不知道是写法问题,还是这个东西不支持协程

已解决

是因为里面面使用了静态数组,把静态的东西放Context

85 0 1
0个回答

🔝