From 3d0884aaec109364ffe3fd66d1a66c73f68aa5d7 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 28 Jan 2025 22:10:00 +1300 Subject: [PATCH] Update hooks --- .env | 2 +- app/controllers/api/databases.php | 97 +++++++++++++++++-------------- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/.env b/.env index 29d95c7bde..479c47e391 100644 --- a/.env +++ b/.env @@ -111,5 +111,5 @@ _APP_WEBHOOK_MAX_FAILED_ATTEMPTS=10 _APP_PROJECT_REGIONS=default _APP_FUNCTIONS_CREATION_ABUSE_LIMIT=5000 _APP_SLOW_QUERIES_MAX_HITS=5 -_APP_SLOW_QUERIES_TIMEOUT=1000 +_APP_SLOW_QUERIES_TIMEOUT=15000 _APP_SLOW_QUERIES_BLOCK=enabled diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 962a3bd70b..928d199d83 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -460,9 +460,14 @@ App::init() $request->getURI(), // Contains databaseId & collectionId $request->getParam('queries') ])); + /** @var Document $document */ - $document = Authorization::skip(fn () => $dbForProject->getDocument('slowQueries', $key)); - if ($document->getAttribute('blocked') === true) { + $document = Authorization::skip(fn () => $dbForProject->getDocument( + 'slowQueries', + $key + )); + + if ($document->getAttribute('blocked')) { throw new Exception(Exception::QUERY_BLOCKED); } }); @@ -473,51 +478,57 @@ App::error() ->inject('request') ->inject('dbForProject') ->action(function (Throwable $error, Request $request, Database $dbForProject) { - if ($error instanceof TimeoutException) { - $route = Request::getRoute(); - $collectionId = $route->getParamValue('collectionId'); - $databaseId = $route->getParamValue('databaseId'); - $queries = $request->getParam('queries', []); + if (!$error instanceof TimeoutException) { + return; + } - $queriesValidator = new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE); - if (!$queriesValidator->isValid($queries)) { - App::setResource('error', fn () => new Exception(Exception::GENERAL_SERVER_ERROR)); - return; + $route = Request::getRoute(); + $collectionId = $route->getParamValue('collectionId'); + $databaseId = $route->getParamValue('databaseId'); + $queries = $request->getParam('queries', []); + + $key = md5(json_encode([ + $request->getMethod(), + $request->getURI(), + $queries + ])); + + /** @var Document $document */ + $document = Authorization::skip(fn () => $dbForProject->getDocument( + 'slowQueries', + $key + )); + + if ($document->isEmpty()) { + $document = Authorization::skip(fn () => $dbForProject->createDocument('slowQueries', new Document([ + '$id' => $key, + 'blocked' => false, + 'count' => 1, + 'queries' => $queries, + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'path' => $request->getURI() + ]))); + } else { + $document->setAttribute('count', $document->getAttribute('count') + 1); + $max = intval(App::getEnv('_APP_SLOW_QUERIES_MAX_HITS', 5)); + + if ($document->getAttribute('count') >= $max) { + $document->setAttribute('blocked', true); } - $key = md5(json_encode([ - $request->getMethod(), - $request->getURI(), // Contains databaseId & collectionId - $request->getParam('queries') - ])); + $document = Authorization::skip(fn () => $dbForProject->updateDocument( + 'slowQueries', + $document->getId(), + $document + )); + } - /** @var Document $document */ - $document = Authorization::skip(fn () => $dbForProject->getDocument('slowQueries', $key)); - if ($document->isEmpty()) { - $document = Authorization::skip(fn () => $dbForProject->createDocument('slowQueries', new Document([ - '$id' => $key, - 'blocked' => false, - 'count' => 1, - 'queries' => $queries, - 'databaseId' => $databaseId, - 'collectionId' => $collectionId, - 'path' => $request->getURI() - ]))); - } else { - $document->setAttribute('count', $document->getAttribute('count') + 1); - $max = intval(App::getEnv('_APP_SLOW_QUERIES_MAX_HITS', 5)); - if ($document->getAttribute('count') >= $max) { - $document->setAttribute('blocked', true); - } - $document = Authorization::skip(fn () => $dbForProject->updateDocument('slowQueries', $document->getId(), $document)); - } - - if ($document->getAttribute('blocked') === true) { - App::setResource('error', fn () => new Exception(Exception::QUERY_BLOCKED)); - return; - } - - App::setResource('error', fn () => new Exception(Exception::QUERY_TIMEOUT)); + // Set the correct exception to pass to the next shutdown hook + if ($document->getAttribute('blocked')) { + App::setResource('error', fn () => new Exception(Exception::QUERY_BLOCKED)); + } else { + App::setResource('error', fn() => new Exception(Exception::QUERY_TIMEOUT)); } });