swoole-framwork/core/lib/DBPool.php
2024-05-21 14:33:56 +08:00

93 lines
2.2 KiB
PHP

<?php
namespace Core\lib;
abstract class DBPool
{
private $min;
private $max;
private $conns;
private $count;
private $idleTime = 40;
abstract protected function newDB();
function __construct($min = 5, $max = 10)
{
$this->min = $min;
$this->max = $max;
$this->conns = new \Swoole\Coroutine\Channel($this->max);
for ($i = 0; $i < $min; $i++) {
$this->addDBToPool();
}
}
public function initPool()
{
/*for ($i = 0; $i < $this->min; $i++) {
$db = $this->newDB();
$this->conns->push($db);
}
$this->count = $this->min;*/
}
public function getConnection()
{
if($this->conns->isEmpty()){
if ($this->count < $this->max) {
$this->addDBToPool();
$dbObject = $this->conns->pop();
}else{
$dbObject = $this->conns->pop(5);
}
}else{
$dbObject = $this->conns->pop();
}
if ($dbObject) {
$dbObject->usedTime = time();
}
return $dbObject;
}
public function close($conn)
{
if ($conn) {
$this->conns->push($conn);
}
}
public function addDBToPool()
{
try {
$this->count++;
$db = $this->newDB();
if (!$db) throw new \Exception('db创建错误');
$dbObject = new \stdClass();
$dbObject->usedTime = time();
$dbObject->db = $db;
$this->conns->push($dbObject);
}catch (\Exception $e) {
$this->count--;
}
}
public function cleanPool()
{
if ($this->conns->length() < $this->min && $this->conns->length()<intval($this->max*0.6)) {
return ;
}
$dbbak = [];
while (true) {
if($this->conns->isEmpty()) {
break;
}
$obj = $this->conns->pop(0.1);
if($this->count > $this->min && (time()-$obj->usedTime) > $this->idleTime){
$this->count--;
} else{
$dbbak[] = $obj;
}
}
foreach ($dbbak as $db){
$this->conns->push($db);
}
}
}