swoole通用协程池的实现

栏目: PHP · 发布时间: 4年前

内容简介:之前过今天看了下swoole相关文档,用PHP也实现了一个,由于swoole官方的协程池是用只能用在Redis。因为协程池代码层耦合了Redis实例化逻辑。

之前过 golang40行代码实现通用协程池

今天看了下swoole相关文档,用 PHP 也实现了一个,由于 swoole 没有 golangselect ,所以实现的有点简单,但是实用性还可以,通过工厂函数实现了通用性。

swoole官方的协程池是用只能用在Redis。因为协程池代码层耦合了 Redis 实例化逻辑。

class RedisPool
{
    /**
     * @var \Swoole\Coroutine\Channel
     */
    protected $pool;

    /**
     * RedisPool constructor.
     * @param int $size 连接池的尺寸
     */
    function __construct($size = 100)
    {
        $this->pool = new Swoole\Coroutine\Channel($size);
        for ($i = 0; $i < $size; $i++)
        {
            $redis = new Swoole\Coroutine\Redis();
            $res = $redis->connect('127.0.0.1', 6379);
            if ($res == false)
            {
                throw new RuntimeException("failed to connect redis server.");
            }
            else
            {
                $this->put($redis);
            }
        }
    }

    function put($redis)
    {
        $this->pool->push($redis);
    }

    function get()
    {
        return $this->pool->pop();
    }
}

利用工厂方法的改造如下:

<?php
/**
 * @author xialeistudio
 * @date 2019-05-20
 */

namespace swoole\foundation\pool;

use Swoole\Coroutine\Channel;

/**
 * Swoole generic connection pool
 * Class Pool
 * @package swoole\foundation\pool
 */
class GenericPool
{
    /**
     * @var int pool size
     */
    private $size = 0;
    /**
     * @var callable construct a connection
     */
    private $factory = null;
    /**
     * @var Channel
     */
    private $channel = null;

    /**
     * GenericPool constructor.
     * @param int $size
     * @param callable $factory
     * @throws InvalidParamException
     */
    public function __construct($size, callable $factory)
    {
        $this->size = $size;
        $this->factory = $factory;
        $this->init();
    }


    /**
     * check pool config
     * @throws InvalidParamException
     */
    private function init()
    {
        if ($this->size <= 0) {
            throw new InvalidParamException('The "size" property must be greater than zero.');
        }
        if (empty($this->factory)) {
            throw new InvalidParamException('The "factory" property must be set.');
        }
        if (!is_callable($this->factory)) {
            throw new InvalidParamException('The "factory" property must be callable.');
        }
        $this->bootstrap();
    }

    /**
     * bootstrap pool
     */
    private function bootstrap()
    {
        $this->channel = new Channel($this->size);

        for ($i = 0; $i < $this->size; $i++) {
            $this->channel->push(call_user_func($this->factory));
        }
    }

    /**
     * Acquire a connection
     * @param int $timeout
     * @return mixed
     */
    public function acquire($timeout = 0)
    {
        return $this->channel->pop($timeout);
    }

    /**
     * Release a resource
     * @param mixed $resource
     */
    public function release($resource)
    {
        $this->channel->push($resource);
    }
}

我们代码里面不关心创建连接的具体逻辑,只要调用工厂方法即可。

项目地址

项目已经开源到github https://github.com/swoole-foundation/swoole-pool


以上所述就是小编给大家介绍的《swoole通用协程池的实现》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Prometheus: Up & Running

Prometheus: Up & Running

Brian Brazil / O'Reilly Media / 2018-7-9 / USD 49.99

Get up to speed with Prometheus, the metrics-based monitoring system used by tens of thousands of organizations in production. This practical guide provides application developers, sysadmins, and DevO......一起来看看 《Prometheus: Up & Running》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具