Add a connection pool class and start utilizing it.

This commit is contained in:
Dave Smith-Hayes 2024-10-09 21:20:52 -04:00
parent f5abbcb8c9
commit f788ba63ae
4 changed files with 27 additions and 13 deletions

View File

@ -26,7 +26,10 @@ use Slovocast\Configuration\SessionSchema;
use Slovocast\Configuration\SiteInformationSchema; use Slovocast\Configuration\SiteInformationSchema;
use Slovocast\Domain\Repository\User\UserRepository; use Slovocast\Domain\Repository\User\UserRepository;
use Slovocast\Domain\Repository\User\UserRepositoryInterface; use Slovocast\Domain\Repository\User\UserRepositoryInterface;
use Slovocast\Infrastructure\Api\Database\ConnectionPoolInterface;
use Slovocast\Infrastructure\Api\User\UserAuthorizationInterface; use Slovocast\Infrastructure\Api\User\UserAuthorizationInterface;
use Slovocast\Infrastructure\Database\ConnectionPoolConfig;
use Slovocast\Infrastructure\Database\ConnectionPool;
use Slovocast\Infrastructure\User\BasicUserAuthorization; use Slovocast\Infrastructure\User\BasicUserAuthorization;
use Twig\Error\LoaderError; use Twig\Error\LoaderError;
@ -125,16 +128,17 @@ class Bootstrap
/** /**
* Database Connections * Database Connections
*/ */
MysqlClient::class => function (ContainerInterface $container) { ConnectionPoolInterface::class => function (ContainerInterface $container) {
$config = $container->get('config')->get('database'); $config = $container->get('config')->get('database');
$connectionString = sprintf(
"%s:%s@%s/%s", $pool = new ConnectionPool(new ConnectionPoolConfig(
rawurlencode($config['username']), $config['username'],
rawurlencode($config['password']), $config['password'],
$config['host'], $config['host'],
$config['database'] $config['database']
); ));
return new MysqlClient($connectionString);
return $pool;
}, },
/** /**
@ -149,7 +153,7 @@ class Bootstrap
*/ */
UserRepositoryInterface::class => function (ContainerInterface $container) { UserRepositoryInterface::class => function (ContainerInterface $container) {
return new UserRepository( return new UserRepository(
$container->get(MysqlClient::class), $container->get(ConnectionPoolInterface::class),
$container->get(UserAuthorizationInterface::class) $container->get(UserAuthorizationInterface::class)
); );
} }

View File

@ -2,16 +2,16 @@
namespace Slovocast\Domain\Repository\User; namespace Slovocast\Domain\Repository\User;
use React\Mysql\MysqlClient;
use Slovocast\Domain\Entity\User; use Slovocast\Domain\Entity\User;
use Slovocast\Exception\EntityNotFoundException; use Slovocast\Exception\EntityNotFoundException;
use Slovocast\Infrastructure\Api\Database\ConnectionPoolInterface;
use Slovocast\Infrastructure\Api\User\UserAuthorizationInterface; use Slovocast\Infrastructure\Api\User\UserAuthorizationInterface;
use function React\Async\await; use function React\Async\await;
class UserRepository implements UserRepositoryInterface class UserRepository implements UserRepositoryInterface
{ {
public function __construct( public function __construct(
private MysqlClient $db, private ConnectionPoolInterface $connectionPool,
private UserAuthorizationInterface $userAuth private UserAuthorizationInterface $userAuth
) {} ) {}
@ -38,7 +38,11 @@ class UserRepository implements UserRepositoryInterface
public function get(int $id): User public function get(int $id): User
{ {
$query = "SELECT * FROM users WHERE id = ? LIMIT 1"; $query = "SELECT * FROM users WHERE id = ? LIMIT 1";
$results = await($this->db->query($query, [ $id ]));
/** @var $conn ConnectionPool */
$conn = $this->connectionPool->getConnection();
$results = await($conn->query($query, [ $id ]));
return $this->userFromQueryResults($results->resultRows[0]); return $this->userFromQueryResults($results->resultRows[0]);
} }

View File

@ -66,11 +66,15 @@ class ConnectionPool implements ConnectionPoolInterface
{ {
if (!$this->hasIdleConnection()) { if (!$this->hasIdleConnection()) {
\React\Async\delay((float) $this->getWaitTimeout()); \React\Async\delay((float) $this->getWaitTimeout());
return this->getConnection(); return $this->getConnection();
} }
// Remove from the idle pool
$conn = $this->idleConnections->current(); $conn = $this->idleConnections->current();
$this->idleConnections->detach($conn); $this->idleConnections->detach($conn);
// Attach to the pool to the connectin, add it to the active pool
$conn->setConnectionPool($this);
$this->activeConnections->attach($conn); $this->activeConnections->attach($conn);
return $conn; return $conn;
} }

View File

@ -30,7 +30,6 @@ class Routes
/** /**
* @param App $app Instantiated Application * @param App $app Instantiated Application
* @return void
*/ */
protected static function users(App $app): void protected static function users(App $app): void
{ {
@ -47,6 +46,9 @@ class Routes
->setName('user-login-action'); ->setName('user-login-action');
} }
/**
* @param App $app Instance of the application
*/
protected static function dashboard(App $app): void protected static function dashboard(App $app): void
{ {
$app->get('/dashboard', DashboardPage::class) $app->get('/dashboard', DashboardPage::class)