从协程中获取链接的方式

本文最后更新于:2023年12月5日 晚上

defer、 invoker、 getObj

go(function () {
    $redisPool = new \App\Pool\RedisPool(new \EasySwoole\Pool\Config(), new \EasySwoole\Redis\Config\RedisConfig(\EasySwoole\EasySwoole\Config::getInstance()->getConf('REDIS')));
    $redis = $redisPool->getObj();
    var_dump($redis->echo('仙士可'));
    $redisPool->recycleObj($redis);
});

go(function () {
    $redisPool = new \App\Pool\RedisPool(new \EasySwoole\Pool\Config(), new \EasySwoole\Redis\Config\RedisConfig(\EasySwoole\EasySwoole\Config::getInstance()->getConf('REDIS')));
    $redisPool->invoke(function (\EasySwoole\Redis\Redis $redis) {
        var_dump($redis->echo('仙士可'));
    });
});

go(function () {
    $redisPool = new \App\Pool\RedisPool(new \EasySwoole\Pool\Config(), new \EasySwoole\Redis\Config\RedisConfig(\EasySwoole\EasySwoole\Config::getInstance()->getConf('REDIS')));
    $redis = $redisPool->defer();
    var_dump($redis->echo('仙士可'));
});

getObj 获取一个连接池对象

​ 通过 getObj 方法获取的对象,都必须调用 unsetObj 或者 recycleObj 进行回收,否则连接池对象会越来越少

invoke 获取一个连接,传入到$call 回调函数中进行处理,回调结束后自动回收连接

​ 通过该方法无需手动回收连接,在回调函数结束后,则自动回收

defer 获取一个连接,协程结束后自动回收

​ 通过该方法无需手动回收连接,在协程结束后,则自动回收

​ 需要注意的事,defer 方法是协程结束后才回收,如果你当前协程运行时间过长,则会一直无法回收,直到协程结束

三者的联系和区别

getObj 获取一个连接池对象, 需要手动回收, 而 defer 中封装了 swoole 的 Coroutine::defer, 在 Coroutine::defer 处理连接池对象的回收。

所以说 getObj 和 defer 的区别就在于回收的时机,前者自己把控,后者只能是在当前协程结束的时候回收。

而 invoke 是传入一个匿名函数,在 invoke 内部执行$obj = $this->getObj(), 然后将$obj 传入匿名函数。利用 try finally, 在匿名函数执行完毕后就回收对象。

总结:本质上都是通过 getObj 获取连接池对象。只不过 defer 和 invoke 又封装了一层,目的都是做到自动回收连接池对象。


从协程中获取链接的方式
http://blog.lujinkai.cn/PHP/EasySwoole/从协程中获取链接的方式/
作者
像方便面一样的男子
发布于
2020年12月11日
更新于
2023年12月5日
许可协议