factory = $container->get(PoolFactory::class); } /** * Get a database connection instance. */ public function connection(?string $name = null): ConnectionInterface { if (is_null($name)) { $name = $this->getDefaultConnection(); } $connection = null; $id = $this->getContextKey($name); if (Context::has($id)) { $connection = Context::get($id); } if (! $connection instanceof ConnectionInterface) { $pool = $this->factory->getPool($name); $connection = $pool->get(); try { // PDO is initialized as an anonymous function, so there is no IO exception, // but if other exceptions are thrown, the connection will not return to the connection pool properly. $connection = $connection->getConnection(); Context::set($id, $connection); } finally { if (Coroutine::inCoroutine()) { defer(function () use ($connection, $id) { Context::set($id, null); $connection->release(); }); } } } return $connection; } /** * Get the default connection name. */ public function getDefaultConnection(): string { return $this->default; } /** * Set the default connection name. */ public function setDefaultConnection(string $name): void { $this->default = $name; } /** * The key to identify the connection object in coroutine context. * @param mixed $name */ private function getContextKey($name): string { return sprintf('database.connection.%s', $name); } }