From 37a2b1cbd9a9dbc1b0bbc6ea45bab45063e60208 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 20 Apr 2026 08:54:31 +0530 Subject: [PATCH] fix: restore executions limit cleanup behind a runtime env flag Per review feedback on the PHPStan cleanup, the two `if ($executionsRetentionCount > 0 && ENABLE_EXECUTIONS_LIMIT_ON_ROUTE)` blocks in `app/controllers/general.php` and `src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php` were load-bearing feature flags, not dead code. Removing them silently dropped the ability to turn the cleanup on later. Changes: - Convert `ENABLE_EXECUTIONS_LIMIT_ON_ROUTE` from `const ... = false;` to a `define()` backed by the new `_APP_EXECUTIONS_LIMIT_ON_ROUTE` env var (defaults to `disabled`). PHPStan can no longer fold the `&&` away since the value is now runtime-resolved, so the guarded blocks are live again. - Restore the `/* cleanup */` block in the `router()` helper in `app/controllers/general.php`. - Restore the two cleanup blocks in `Functions/Http/Executions/Create.php` (one on the async-scheduled return path, one on the sync-response path), and re-add the `DeleteEvent $queueForDeletes` / `int $executionsRetentionCount` injections plus the `Appwrite\Event\Delete` import. Runtime behavior is identical to main (flag off by default); operators can now flip it via env without a code change. --- app/controllers/general.php | 14 +++++++++++ app/init/constants.php | 3 ++- .../Functions/Http/Executions/Create.php | 23 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 06ed676a76..a17f0dff04 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -771,6 +771,20 @@ function router(Http $utopia, Database $dbForPlatform, callable $getProjectDB, S deployment: $deployment->getArrayCopy(), )); + /* cleanup */ + if ($executionsRetentionCount > 0 && ENABLE_EXECUTIONS_LIMIT_ON_ROUTE) { + $resourceType = $type === 'function' + ? RESOURCE_TYPE_FUNCTIONS + : RESOURCE_TYPE_SITES; + + $queueForDeletes + ->setProject($project) + ->setResourceType($resourceType) + ->setResource($resource->getSequence()) + ->setType(DELETE_TYPE_EXECUTIONS_LIMIT) + ->trigger(); + } + return true; } elseif ($type === 'api') { return false; diff --git a/app/init/constants.php b/app/init/constants.php index f2127cd666..fa090a648c 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -1,6 +1,7 @@ inject('executor') ->inject('platform') ->inject('authorization') + ->inject('queueForDeletes') + ->inject('executionsRetentionCount') ->callback($this->action(...)); } @@ -126,6 +129,8 @@ class Create extends Base Executor $executor, array $platform, Authorization $authorization, + DeleteEvent $queueForDeletes, + int $executionsRetentionCount, ) { $async = \strval($async) === 'true' || \strval($async) === '1'; @@ -331,6 +336,15 @@ class Create extends Base $execution = $authorization->skip(fn () => $dbForProject->createDocument('executions', $execution)); } + if ($executionsRetentionCount > 0 && ENABLE_EXECUTIONS_LIMIT_ON_ROUTE) { + $queueForDeletes + ->setProject($project) + ->setResource($function->getSequence()) + ->setResourceType(RESOURCE_TYPE_FUNCTIONS) + ->setType(DELETE_TYPE_EXECUTIONS_LIMIT) + ->trigger(); + } + $response->setStatusCode(Response::STATUS_CODE_ACCEPTED); $response->dynamic($execution, Response::MODEL_EXECUTION); return; @@ -509,6 +523,15 @@ class Create extends Base } } + if ($executionsRetentionCount > 0 && ENABLE_EXECUTIONS_LIMIT_ON_ROUTE) { + $queueForDeletes + ->setProject($project) + ->setResource($function->getSequence()) + ->setResourceType(RESOURCE_TYPE_FUNCTIONS) + ->setType(DELETE_TYPE_EXECUTIONS_LIMIT) + ->trigger(); + } + $response ->setStatusCode(Response::STATUS_CODE_CREATED) ->dynamic($execution, Response::MODEL_EXECUTION);