From 6edd04cf30e9486c8a61ebd5b5cc61f0cda502ba Mon Sep 17 00:00:00 2001
From: Mateusz Charytoniuk <mateusz.charytoniuk@protonmail.com>
Date: Mon, 16 Oct 2023 21:16:08 +0200
Subject: [PATCH] chore: add pool preconnect option

---
 src/DatabaseConnectionPoolConfiguration.php        |  2 ++
 src/DependencyInjectionContainer.php               | 14 +++++++++++---
 src/RedisConnectionPoolConfiguration.php           |  2 ++
 .../DatabaseConfigurationProvider.php              |  3 +++
 .../RedisConfigurationProvider.php                 |  3 +++
 .../DatabaseConnectionPoolRepositoryProvider.php   |  5 ++++-
 .../RedisConnectionPoolRepositoryProvider.php      |  5 ++++-
 7 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/src/DatabaseConnectionPoolConfiguration.php b/src/DatabaseConnectionPoolConfiguration.php
index 1681fab6..586a22a6 100644
--- a/src/DatabaseConnectionPoolConfiguration.php
+++ b/src/DatabaseConnectionPoolConfiguration.php
@@ -20,6 +20,8 @@ readonly class DatabaseConnectionPoolConfiguration
         #[SensitiveParameter]
         public string $password,
         #[SensitiveParameter]
+        public bool $poolPrefill,
+        #[SensitiveParameter]
         public int $poolSize,
         #[SensitiveParameter]
         public int $port,
diff --git a/src/DependencyInjectionContainer.php b/src/DependencyInjectionContainer.php
index 06550b49..94ff6132 100644
--- a/src/DependencyInjectionContainer.php
+++ b/src/DependencyInjectionContainer.php
@@ -13,6 +13,7 @@ use ReflectionClass;
 use ReflectionFunction;
 use RuntimeException;
 use Swoole\Coroutine\WaitGroup;
+use Throwable;
 
 use function Swoole\Coroutine\run;
 
@@ -260,10 +261,17 @@ readonly class DependencyInjectionContainer
             return $this->singletons->get($className);
         }
 
-        $singleton = $this->doMakeSingleton($className, $previous);
+        try {
+            $singleton = $this->doMakeSingleton($className, $previous);
 
-        $this->singletons->set($className, $singleton);
+            $this->singletons->set($className, $singleton);
 
-        return $singleton;
+            return $singleton;
+        } catch (Throwable $throwable) {
+            throw new LogicException(
+                message: 'Error while building: '.$className,
+                previous: $throwable,
+            );
+        }
     }
 }
diff --git a/src/RedisConnectionPoolConfiguration.php b/src/RedisConnectionPoolConfiguration.php
index 3e56da1a..ff9f65dd 100644
--- a/src/RedisConnectionPoolConfiguration.php
+++ b/src/RedisConnectionPoolConfiguration.php
@@ -16,6 +16,8 @@ readonly class RedisConnectionPoolConfiguration
         #[SensitiveParameter]
         public string $password,
         #[SensitiveParameter]
+        public bool $poolPrefill,
+        #[SensitiveParameter]
         public int $poolSize,
         #[SensitiveParameter]
         public int $port,
diff --git a/src/SingletonProvider/ConfigurationProvider/DatabaseConfigurationProvider.php b/src/SingletonProvider/ConfigurationProvider/DatabaseConfigurationProvider.php
index 6312452c..aeacb633 100644
--- a/src/SingletonProvider/ConfigurationProvider/DatabaseConfigurationProvider.php
+++ b/src/SingletonProvider/ConfigurationProvider/DatabaseConfigurationProvider.php
@@ -20,6 +20,7 @@ use Nette\Schema\Schema;
  *         host: string,
  *         log_queries: bool,
  *         password: string,
+ *         pool_prefill: bool,
  *         pool_size: int,
  *         port: int,
  *         username: string,
@@ -44,6 +45,7 @@ final readonly class DatabaseConfigurationProvider extends ConfigurationProvider
             'host' => Expect::string()->min(1)->required(),
             'log_queries' => Expect::bool()->required(),
             'password' => Expect::string()->required(),
+            'pool_prefill' => Expect::bool()->required(),
             'pool_size' => Expect::int()->min(1)->required(),
             'port' => Expect::int()->min(1)->max(65535)->required(),
             'username' => Expect::string()->min(1)->required(),
@@ -65,6 +67,7 @@ final readonly class DatabaseConfigurationProvider extends ConfigurationProvider
                     host: $connectionPoolConfiguration->host,
                     logQueries: $connectionPoolConfiguration->log_queries,
                     password: $connectionPoolConfiguration->password,
+                    poolPrefill: $connectionPoolConfiguration->pool_prefill,
                     poolSize: $connectionPoolConfiguration->pool_size,
                     port: $connectionPoolConfiguration->port,
                     username: $connectionPoolConfiguration->username,
diff --git a/src/SingletonProvider/ConfigurationProvider/RedisConfigurationProvider.php b/src/SingletonProvider/ConfigurationProvider/RedisConfigurationProvider.php
index 3f202034..950377e2 100644
--- a/src/SingletonProvider/ConfigurationProvider/RedisConfigurationProvider.php
+++ b/src/SingletonProvider/ConfigurationProvider/RedisConfigurationProvider.php
@@ -18,6 +18,7 @@ use Nette\Schema\Schema;
  *         db_index: int,
  *         host: string,
  *         password: string,
+ *         pool_prefill: bool,
  *         pool_size: int,
  *         port: int,
  *         prefix: string,
@@ -41,6 +42,7 @@ final readonly class RedisConfigurationProvider extends ConfigurationProvider
             'db_index' => Expect::int()->min(0)->required(),
             'host' => Expect::string()->min(1)->required(),
             'password' => Expect::string()->required(),
+            'pool_prefill' => Expect::bool()->required(),
             'pool_size' => Expect::int()->min(1)->required(),
             'port' => Expect::int()->min(1)->max(65535)->required(),
             'prefix' => Expect::string()->min(1)->required(),
@@ -61,6 +63,7 @@ final readonly class RedisConfigurationProvider extends ConfigurationProvider
                     dbIndex: $connectionPoolConfiguration->db_index,
                     host: $connectionPoolConfiguration->host,
                     password: $connectionPoolConfiguration->password,
+                    poolPrefill: $connectionPoolConfiguration->pool_prefill,
                     poolSize: $connectionPoolConfiguration->pool_size,
                     port: $connectionPoolConfiguration->port,
                     prefix: $connectionPoolConfiguration->prefix,
diff --git a/src/SingletonProvider/DatabaseConnectionPoolRepositoryProvider.php b/src/SingletonProvider/DatabaseConnectionPoolRepositoryProvider.php
index ee16d39e..67c47947 100644
--- a/src/SingletonProvider/DatabaseConnectionPoolRepositoryProvider.php
+++ b/src/SingletonProvider/DatabaseConnectionPoolRepositoryProvider.php
@@ -48,7 +48,10 @@ final readonly class DatabaseConnectionPoolRepositoryProvider extends SingletonP
             ;
 
             $pdoPool = new PDOPool($pdoConfig, $connectionPoolConfiguration->poolSize);
-            $pdoPool->fill();
+
+            if ($connectionPoolConfiguration->poolPrefill) {
+                $pdoPool->fill();
+            }
 
             $databaseConnectionPoolRepository->databaseConnectionPool->put($name, $pdoPool);
         }
diff --git a/src/SingletonProvider/RedisConnectionPoolRepositoryProvider.php b/src/SingletonProvider/RedisConnectionPoolRepositoryProvider.php
index 7e494f5a..741f9999 100644
--- a/src/SingletonProvider/RedisConnectionPoolRepositoryProvider.php
+++ b/src/SingletonProvider/RedisConnectionPoolRepositoryProvider.php
@@ -39,7 +39,10 @@ final readonly class RedisConnectionPoolRepositoryProvider extends SingletonProv
             ;
 
             $redisPool = new RedisPool($redisConfig, $connectionPoolConfiguration->poolSize);
-            $redisPool->fill();
+
+            if ($connectionPoolConfiguration->poolPrefill) {
+                $redisPool->fill();
+            }
 
             $redisConnectionPoolRepository->redisConnectionPool->put($name, $redisPool);
         }
-- 
GitLab