<?php
namespace Yesf\Connection;
use SplQueue;
use Swoole\Coroutine as co;
use Yesf\Swoole;
use Yesf\Connection\Pool;
use Yesf\Exception\NotFoundException;
trait PoolTrait {
protected $connection = null;
protected $connection_count = 0;
protected $last_run_out_time = null;
protected $wait = null;
protected $min_client = PHP_INT_MAX;
protected $max_client = PHP_INT_MAX;
public function initPool($config) {
if (!method_exists($this, 'getMinClient') || !method_exists($this, 'getMaxClient')) {
throw new NotFoundException("Method getMinClient or getMaxClient not found");
}
$this->wait = new SplQueue;
$this->connection = new SplQueue;
$this->last_run_out_time = time();
if (isset($config['min'])) {
$this->min_client = intval($config['min']);
}
if (isset($config['max'])) {
$this->max_client = intval($config['max']);
}
$count = $this->getMinClient();
while ($count--) {
$this->createConnection();
}
}
protected function getMinClient() {
return $this->min_client === PHP_INT_MAX ? Pool::getMin() : $this->min_client;
}
protected function getMaxClient() {
return $this->max_client === PHP_INT_MAX ? Pool::getMax() : $this->max_client;
}
public function getConnection() {
if ($this->connection->count() === 0) {
if ($this->getMaxClient() > $this->connection_count) {
$this->last_run_out_time = time();
return $this->connect();
}
$uid = co::getUid();
$this->wait->push($uid);
co::suspend();
return $this->connection->pop();
}
if ($this->connection->count() === 1) {
$this->last_run_out_time = time();
}
return $this->connection->pop();
}
public function freeConnection($connection) {
$this->connection->push($connection);
if ($this->wait->count() > 0) {
$uid = $this->wait->pop();
co::resume($uid);
} else {
if ($this->connection_count > $this->getMinClient() && time() - $this->last_run_out_time > 15) {
$this->close();
}
}
}
public function close() {
$this->connection_count--;
}
protected function createConnection() {
$this->connection->push($this->connect());
$this->connection_count++;
}
protected function connect() {
}
public function reconnect($connection) {
$this->close();
return $this->connect();
}
}