feat: realtime db pool
This commit is contained in:
parent
42f0bddd60
commit
ebc971f8dc
3 changed files with 29 additions and 92 deletions
|
@ -101,13 +101,6 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
|||
if (!$dbForConsole->getCollection($key)->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
/**
|
||||
* Skip to prevent 0.15 migration issues.
|
||||
*/
|
||||
if ($key === 'databases' && $dbForConsole->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'), 'collections')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Console::success('[Setup] - Creating collection: ' . $collection['$id'] . '...');
|
||||
|
||||
$attributes = [];
|
||||
|
|
102
app/realtime.php
102
app/realtime.php
|
@ -333,70 +333,48 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
|
|||
$request = new Request($request);
|
||||
$response = new Response(new SwooleResponse());
|
||||
|
||||
/** @var PDO $db */
|
||||
$dbPool = $register->get('dbPool');
|
||||
$consoleDB = $dbPool->getConsoleDBFromPool();
|
||||
App::setResource('request', fn() => $request);
|
||||
App::setResource('response', fn() => $response);
|
||||
|
||||
/** @var Redis $redis */
|
||||
$redis = $register->get('redisPool')->get();
|
||||
App::setResource('cache', fn() => $redis);
|
||||
|
||||
/** @var PDO $db */
|
||||
$dbPool = $register->get('dbPool');
|
||||
App::setResource('dbPool', fn() => $dbPool);
|
||||
|
||||
Console::info("Connection open (user: {$connection})");
|
||||
|
||||
App::setResource('consoleDB', fn() => $consoleDB);
|
||||
App::setResource('cache', fn () => $redis);
|
||||
App::setResource('request', fn () => $request);
|
||||
App::setResource('response', fn () => $response);
|
||||
|
||||
try {
|
||||
/** @var \Utopia\Database\Document $project */
|
||||
$project = $app->getResource('project');
|
||||
|
||||
/** @var \Utopia\Database\Document $console */
|
||||
$console = $app->getResource('console');
|
||||
|
||||
$cache = new Cache(new RedisCache($redis));
|
||||
$database = new Database(new MariaDB($db), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$database->setNamespace("_{$project->getInternalId()}");
|
||||
[$dbForConsole, $returnConsoleDB] = $dbPool->getDBFromPool('console', $redis);
|
||||
App::setResource('dbForConsole', fn() => $dbForConsole);
|
||||
|
||||
/** @var \Utopia\Database\Document $project */
|
||||
$project = $app->getResource('project');
|
||||
|
||||
/*
|
||||
* Project Check
|
||||
*/
|
||||
// var_dump($project);
|
||||
if (empty($project->getId())) {
|
||||
throw new Exception('Missing or unknown project ID', 1008);
|
||||
}
|
||||
|
||||
$projectId = $project->getId();
|
||||
$projectDB = $consoleDB;
|
||||
if ($projectId !== 'console') {
|
||||
$dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */
|
||||
$project = Authorization::skip(fn() => $dbForConsole->getDocument('projects', $projectId));
|
||||
$dbName = $project->getAttribute('database', '');
|
||||
if (!empty($dbName)) {
|
||||
$projectDB = $dbPool->getDBFromPool($dbName);
|
||||
}
|
||||
}
|
||||
|
||||
App::setResource('projectDB', fn() => $projectDB);
|
||||
[$dbForProject, $returnProjectDB] = $dbPool->getDBFromPool($project->getId(), $redis);
|
||||
App::setResource('dbForProject', fn() => $dbForProject);
|
||||
|
||||
/** @var \Utopia\Database\Document $user */
|
||||
$user = $app->getResource('user');
|
||||
|
||||
/** @var \Utopia\Database\Document $console */
|
||||
$console = $app->getResource('console');
|
||||
|
||||
$cache = new Cache(new RedisCache($redis));
|
||||
$database = new Database(new MariaDB($projectDB), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$database->setNamespace("_{$project->getId()}");
|
||||
|
||||
/*
|
||||
* Abuse Check
|
||||
*
|
||||
* Abuse limits are connecting 128 times per minute and ip address.
|
||||
*/
|
||||
$timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, $database);
|
||||
$timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, $dbForProject);
|
||||
$timeLimit
|
||||
->setParam('{ip}', $request->getIP())
|
||||
->setParam('{url}', $request->getURI());
|
||||
|
@ -475,13 +453,8 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
|
|||
/**
|
||||
* Put used PDO and Redis Connections back into their pools.
|
||||
*/
|
||||
/** @var PDOPool $consolePool */
|
||||
$dbPool->putConsoleDb($consoleDB);
|
||||
|
||||
if (!empty($dbName) && !empty($projectDB)) {
|
||||
$dbPool->put($projectDB, $dbName);
|
||||
}
|
||||
|
||||
call_user_func($returnConsoleDB);
|
||||
call_user_func($returnProjectDB);
|
||||
$register->get('redisPool')->put($redis);
|
||||
}
|
||||
});
|
||||
|
@ -490,42 +463,19 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
|
|||
try {
|
||||
$response = new Response(new SwooleResponse());
|
||||
|
||||
$dbPool = $register->get('dbPool');
|
||||
$consoleDB = $dbPool->getConsoleDBFromPool();
|
||||
$projectId = $realtime->connections[$connection]['projectId'];
|
||||
|
||||
$redis = $register->get('redisPool')->get();
|
||||
$cache = new Cache(new RedisCache($redis));
|
||||
|
||||
|
||||
$projectId = $realtime->connections[$connection]['projectId'];
|
||||
$projectDB = $consoleDB;
|
||||
if ($projectId !== 'console') {
|
||||
$dbForConsole = new Database(new MariaDB($projectDB), $cache);
|
||||
$dbForConsole->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$dbForConsole->setNamespace("_console");
|
||||
$project = Authorization::skip(fn() => $dbForConsole->getDocument('projects', $projectId));
|
||||
$dbName = $project->getAttribute('database', '');
|
||||
if (!empty($dbName)) {
|
||||
$projectDB = $dbPool->getDBFromPool($dbName);
|
||||
}
|
||||
}
|
||||
|
||||
$database = new Database(new MariaDB($projectDB), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$database->setNamespace("_console");
|
||||
$projectId = $realtime->connections[$connection]['projectId'];
|
||||
|
||||
if ($projectId !== 'console') {
|
||||
$project = Authorization::skip(fn() => $database->getDocument('projects', $projectId));
|
||||
$database->setNamespace("_{$project->getInternalId()}");
|
||||
}
|
||||
$dbPool = $register->get('dbPool');
|
||||
[$dbForProject, $returnProjectDB] = $dbPool->getDBFromPool($projectId, $redis);
|
||||
|
||||
/*
|
||||
* Abuse Check
|
||||
*
|
||||
* Abuse limits are sending 32 times per minute and connection.
|
||||
*/
|
||||
$timeLimit = new TimeLimit('url:{url},connection:{connection}', 32, 60, $database);
|
||||
$timeLimit = new TimeLimit('url:{url},connection:{connection}', 32, 60, $dbForProject);
|
||||
|
||||
$timeLimit
|
||||
->setParam('{connection}', $connection)
|
||||
|
@ -556,7 +506,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
|
|||
Auth::$unique = $session['id'] ?? '';
|
||||
Auth::$secret = $session['secret'] ?? '';
|
||||
|
||||
$user = $database->getDocument('users', Auth::$unique);
|
||||
$user = $dbForProject->getDocument('users', Auth::$unique);
|
||||
|
||||
if (
|
||||
empty($user->getId()) // Check a document has been found in the DB
|
||||
|
@ -601,13 +551,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
|
|||
$server->close($connection, $th->getCode());
|
||||
}
|
||||
} finally {
|
||||
/** @var PDOPool $consolePool */
|
||||
$dbPool->putConsoleDb($consoleDB);
|
||||
|
||||
if (!empty($dbName) && !empty($projectDB)) {
|
||||
$dbPool->put($projectDB, $dbName);
|
||||
}
|
||||
|
||||
call_user_func($returnProjectDB);
|
||||
$register->get('redisPool')->put($redis);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -130,7 +130,7 @@ class DatabasePool {
|
|||
$cache = new Cache(new RedisCache($redis));
|
||||
$database = new Database(new MariaDB($pdo), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$namespace = "_project_console";
|
||||
$namespace = "_console";
|
||||
$database->setNamespace($namespace);
|
||||
|
||||
$project = Authorization::skip(fn() => $database->getDocument('projects', $projectID));
|
||||
|
@ -161,7 +161,7 @@ class DatabasePool {
|
|||
$cache = new Cache(new RedisCache($redis));
|
||||
$database = new Database(new MariaDB($pdo), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$namespace = "_project_$internalID";
|
||||
$namespace = "_$internalID";
|
||||
$database->setNamespace($namespace);
|
||||
|
||||
return $database;
|
||||
|
@ -186,7 +186,7 @@ class DatabasePool {
|
|||
[$name, $internalID] = $this->getName($projectID, $redis);
|
||||
$pool = $this->pools[$name] ?? throw new Exception("Database pool with name : $name not found. Check the value of _APP_PROJECT_DB in .env", 500);
|
||||
|
||||
$namespace = "_project_$internalID";
|
||||
$namespace = "_$internalID";
|
||||
$attempts = 0;
|
||||
do {
|
||||
try {
|
||||
|
|
Loading…
Reference in a new issue