PHP实现简单的连接池

<?php
namespace app\swoole\controller;


/**
 * 通用的连接池
 */
abstract class Pool
{
	/**
	 * 连接池的尺寸,最大连接数
	 * @var int $poolSize
	 */
	protected $poolSize;

	/**
	 * 连接池的资源
	 * @var array $resourcePool
	 */
	protected $resourcePool = array();

	protected $resourceNum = 0;
	protected $failureCount = 0;

	/**
	 * @var \SplQueue
	 */
	protected $idlePool;

	/**
	 * @var \SplQueue
	 */
	protected $taskQueue;

	protected $createFunction;

	protected $config;

	/**
	 * @param int $poolSize
	 * @param array $config
	 * @throws \Exception
	 */
	public function __construct($config = array(), $poolSize = 100)
	{
		$this->poolSize = $poolSize;
		$this->taskQueue = new \SplQueue();
		$this->idlePool = new \SplQueue();
		$this->config = $config;
	}

	/**
	 * 加入到连接池中
	 * @param $resource
	 */
	public function join($resource)
	{
		//保存到空闲连接池中
		$this->resourcePool[spl_object_hash($resource)] = $resource;
		$this->release($resource);
	}

	/**
	 * 释放资源
	 * @param $resource
	 */
	public function release($resource)
	{
		$this->idlePool->enqueue($resource);
		//有任务要做
		if (count($this->taskQueue) > 0)
		{
			$this->doTask();
		}
	}

	/**
	 * @param $callback
	 */
	public function create($callback)
	{
		$this->createFunction = $callback;
	}
	/**
	 * 失败计数
	 */
	public function failure()
	{
		$this->resourceNum--;
		$this->failureCount++;
	}

	/**
	 * 修改连接池尺寸
	 * @param $newSize
	 */
	public function setPoolSize($newSize)
	{
		$this->poolSize = $newSize;
	}

	/**
	 * 移除资源
	 * @param $resource
	 * @return bool
	 */
	public function remove($resource)
	{
		$rid = spl_object_hash($resource);
		if (!isset($this->resourcePool[$rid]))
		{
			return false;
		}
		//从resourcePool中删除
		unset($this->resourcePool[$rid]);
		$this->resourceNum--;
		return true;
	}

	/**
	 * 请求资源
	 * @param callable $callback
	 * @return bool
	 */
	public function request(callable $callback)
	{

		// 1.先入taskQueue,再入idlePool队列
		//入队列
		$this->taskQueue->enqueue($callback);
			//有可用资源
		if (count($this->idlePool) > 0){
			$this->doTask();
		} elseif (count($this->resourcePool) < $this->poolSize && $this->resourceNum < $this->poolSize){
			//没有可用的资源, 创建新的连接,直接调用到Swredis中的connect方法 连接swoole_redis
			call_user_func($this->createFunction);
			$this->resourceNum++;

		}
	}

	// 查询连接池中是否存在可用的资源
	protected function doTask()
	{
		$resource = null;
		//从空闲队列中取出可用的资源
		while (count($this->idlePool) > 0){
			// 从连接池中拿取连接
			$_resource = $this->idlePool->dequeue();
			$rid = spl_object_hash($_resource);
			//资源已经不可用了,连接已关闭
			if (!isset($this->resourcePool[$rid])){
				continue;
			} else {
				//找到可用连接
				$resource = $_resource;
				break;
			}
		}
		//没有可用连接,继续等待
		if (!$resource){
			if (count($this->resourcePool) == 0){
				call_user_func($this->createFunction);
				$this->resourceNum++;
			}
			return;
		}
		// 已经拿到连接之后,将taskQueue任务队列中的首个连接踢出,表示已经拿了连接,完成了任务
		$callback = $this->taskQueue->dequeue();

		call_user_func($callback, $resource);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值