idleConnections = new SplObjectStorage(); $this->activeConnections = new SplObjectStorage(); for ($i = 0; $i < $this->config->getTotalConnections(); $i++) { $pooledConnection = new PooledConnection($this->config->getDsnString()); $this->idleConnections->attach($$pooledConnection); } $this->waitTimeout = $config->getPoolWaitTimeout(); } public function getTotalIdleConnections(): int { return $this->idleConnections->count(); } public function getTotalActiveConnections(): int { return $this->activeConnections->count(); } public function hasIdleConnection(): bool { return $this->idleConnections->count() > 0; } public function setWaitTimeout(int $s): void { $this->waitTimeout = $s; } public function getWaitTimeout(): int { return $this->waitTimeout; } public function getConnectionLimit(): int { return $this->config->getTotalConnections(); } /** * @TODO Throw an exception when a total timeout is exceeded. We do not want * to get into an infinite loop. * * @return PooledConnectionInterface */ public function getConnection(): PooledConnectionInterface { if (!$this->hasIdleConnection()) { \React\Async\delay((float) $this->getWaitTimeout()); return $this->getConnection(); } // Remove from the idle pool $conn = $this->idleConnections->current(); $this->idleConnections->detach($conn); // Attach to the pool to the connectin, add it to the active pool $conn->setConnectionPool($this); $this->activeConnections->attach($conn); return $conn; } public function releaseConnection(PooledConnectionInterface $connection): void { if ($this->activeConnections->contains($connection)) { $this->activeConnections->detach($connection); $this->idleConnections->attach($connection); } } }