From 3ab4dcb7c1b1ac8ec5f3a6cdeb5a32ed1b255070 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Fri, 1 Jul 2022 15:43:38 +0200 Subject: [PATCH] feat: refactor DatabasePool class --- app/init.php | 4 -- app/tasks/doctor.php | 2 +- app/tasks/maintenance.php | 3 +- app/tasks/specs.php | 2 +- app/tasks/usage.php | 6 +-- docker-compose.yml | 73 +++++++------------------- src/Appwrite/Database/DatabasePool.php | 6 +-- src/Appwrite/Resque/Worker.php | 51 +++++++++--------- 8 files changed, 50 insertions(+), 97 deletions(-) diff --git a/app/init.php b/app/init.php index bd1f40a1f..2b518c797 100644 --- a/app/init.php +++ b/app/init.php @@ -18,13 +18,11 @@ ini_set('display_startup_errors', 1); ini_set('default_socket_timeout', -1); error_reporting(E_ALL); -use Appwrite\Extend\PDO; use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; use Appwrite\Extend\Exception; use Appwrite\Auth\Auth; use Appwrite\Database\DatabasePool; -use Appwrite\DSN\DSN; use Appwrite\Event\Audit; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Delete; @@ -52,8 +50,6 @@ use Utopia\Database\Validator\Structure; use Utopia\Database\Validator\Authorization; use Utopia\Validator\Range; use Utopia\Validator\WhiteList; -use Swoole\Database\PDOConfig; -use Swoole\Database\PDOPool; use Swoole\Database\RedisConfig; use Swoole\Database\RedisPool; use Utopia\Database\Query; diff --git a/app/tasks/doctor.php b/app/tasks/doctor.php index ea0a963a7..c937884be 100644 --- a/app/tasks/doctor.php +++ b/app/tasks/doctor.php @@ -96,7 +96,7 @@ $cli } try { - $register->get('consoleDB'); /* @var $db PDO */ + $register->get('dbPool')->getConsoleDB(); /* @var $db PDO */ Console::success('Database............connected 👍'); } catch (\Throwable $th) { Console::error('Database.........disconnected 👎'); diff --git a/app/tasks/maintenance.php b/app/tasks/maintenance.php index 54963d413..54a30de8c 100644 --- a/app/tasks/maintenance.php +++ b/app/tasks/maintenance.php @@ -24,7 +24,8 @@ function getConsoleDB(): Database try { $attempts++; $cache = new Cache(new RedisCache($register->get('cache'))); - $database = new Database(new MariaDB($register->get('consoleDB')), $cache); + $consoleDB = $register->get('dbPool')->getConsoleDB(); + $database = new Database(new MariaDB($consoleDB), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_console'); // Main DB diff --git a/app/tasks/specs.php b/app/tasks/specs.php index f1c9f6b27..a7032dd22 100644 --- a/app/tasks/specs.php +++ b/app/tasks/specs.php @@ -19,7 +19,7 @@ $cli ->param('version', 'latest', new Text(8), 'Spec version', true) ->param('mode', 'normal', new WhiteList(['normal', 'mocks']), 'Spec Mode', true) ->action(function ($version, $mode) use ($register) { - $consoleDB = $register->get('consoleDB'); + $consoleDB = $register->get('dbPool')->getConsoleDB(); $redis = $register->get('cache'); $appRoutes = App::getRoutes(); $response = new Response(new HttpResponse()); diff --git a/app/tasks/usage.php b/app/tasks/usage.php index c61d38598..f7e5ffb89 100644 --- a/app/tasks/usage.php +++ b/app/tasks/usage.php @@ -237,13 +237,13 @@ $cli $attempts = 0; $max = 10; $sleep = 1; - + $dbPool = $register->get('dbPool'); $consoleDB = null; $redis = null; do { // connect to db try { $attempts++; - $consoleDB = $register->get('consoleDB'); + $consoleDB = $dbPool->getConsoleDB(); $redis = $register->get('cache'); break; // leave the do-while if successful } catch (\Exception $e) { @@ -261,8 +261,6 @@ $cli $dbForConsole->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $dbForConsole->setNamespace('_console'); - $dbPool = $register->get('dbPool'); - $latestTime = []; Authorization::disable(); diff --git a/docker-compose.yml b/docker-compose.yml index 3e3f307d8..bbc5d83f7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -138,11 +138,6 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - _APP_PROJECT_DB - _APP_CONSOLE_DB - _APP_SMTP_HOST @@ -218,12 +213,8 @@ services: - _APP_OPENSSL_KEY_V1 - _APP_REDIS_HOST - _APP_REDIS_PORT - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - _APP_USAGE_STATS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG @@ -249,12 +240,8 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG @@ -310,12 +297,8 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - *x-env-storage - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG @@ -344,12 +327,8 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG @@ -376,12 +355,8 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG @@ -411,12 +386,8 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG @@ -442,12 +413,8 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - _APP_FUNCTIONS_TIMEOUT - _APP_EXECUTOR_SECRET - _APP_EXECUTOR_HOST @@ -555,12 +522,8 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - _APP_MAINTENANCE_INTERVAL - _APP_MAINTENANCE_RETENTION_EXECUTION - _APP_MAINTENANCE_RETENTION_ABUSE @@ -586,8 +549,8 @@ services: environment: - _APP_ENV - _APP_OPENSSL_KEY_V1 - - - _APP_DB + - _APP_CONSOLE_DB + - _APP_PROJECT_DB - _APP_INFLUXDB_HOST - _APP_INFLUXDB_PORT - _APP_USAGE_AGGREGATION_INTERVAL diff --git a/src/Appwrite/Database/DatabasePool.php b/src/Appwrite/Database/DatabasePool.php index 29c2ad61b..de7135f76 100644 --- a/src/Appwrite/Database/DatabasePool.php +++ b/src/Appwrite/Database/DatabasePool.php @@ -81,11 +81,7 @@ class DatabasePool { */ public function getDB(string $name): ?PDO { - $dsn = $this->dsn[$name] ?? false; - - if ($dsn === false) { - throw new Exception("Database with name : $name not found.", 500); - } + $dsn = $this->databases[$name] ?? throw new Exception("Database with name : $name not found.", 500); $dsn = new DSN($dsn); $dbHost = $dsn->getHost(); diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index 84feb0f96..d3fbccea0 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -17,6 +17,7 @@ use Utopia\Storage\Device\Wasabi; use Utopia\Storage\Device\Backblaze; use Utopia\Storage\Device\S3; use Exception; +use PDO; abstract class Worker { @@ -159,7 +160,20 @@ abstract class Worker */ protected function getProjectDB(string $projectId): Database { - return $this->getDB(self::DATABASE_PROJECT, $projectId); + if (!$projectId) { + throw new \Exception('ProjectID not provided - cannot get database'); + } + $namespace = "_{$projectId}"; + + global $register; + $dbForConsole = $this->getConsoleDB(); + $project = $dbForConsole->getDocument('projects', $projectId); + $dbName = $project->getAttribute('database', ''); + + $projectDB = $register->get('dbPool')->getDB($dbName); + + + return $this->getDB(self::DATABASE_PROJECT, $projectDB, $namespace); } /** @@ -168,7 +182,12 @@ abstract class Worker */ protected function getConsoleDB(): Database { - return $this->getDB(self::DATABASE_CONSOLE); + global $register; + $consoleDB = $register->get('dbPool')->getConsoleDB(); + $namespace = "_console"; + $sleep = 5; // ConsoleDB needs extra sleep time to ensure tables are created + + return $this->getDB(self::DATABASE_CONSOLE, $consoleDB, $namespace, $sleep); } /** @@ -177,36 +196,16 @@ abstract class Worker * @param string $projectId of internal or external DB * @return Database */ - private function getDB($type, $projectId = ''): Database + private function getDB(string $type, PDO $pdo, string $namespace, int $sleep = DATABASE_RECONNECT_SLEEP): Database { global $register; - - $namespace = ''; - $sleep = DATABASE_RECONNECT_SLEEP; // overwritten when necessary - - switch ($type) { - case self::DATABASE_PROJECT: - if (!$projectId) { - throw new \Exception('ProjectID not provided - cannot get database'); - } - $namespace = "_{$projectId}"; - break; - case self::DATABASE_CONSOLE: - $namespace = "_console"; - $sleep = 5; // ConsoleDB needs extra sleep time to ensure tables are created - break; - default: - throw new \Exception('Unknown database type: ' . $type); - break; - } - + $cache = $register->get('cache'); $attempts = 0; - do { try { $attempts++; - $cache = new Cache(new RedisCache($register->get('cache'))); - $database = new Database(new MariaDB($register->get('db')), $cache); + $cache = new Cache(new RedisCache($cache)); + $database = new Database(new MariaDB($pdo), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace($namespace); // Main DB