diff --git a/app/config/runtimes/specifications.php b/app/config/runtimes/specifications.php deleted file mode 100644 index d3625db8a2..0000000000 --- a/app/config/runtimes/specifications.php +++ /dev/null @@ -1,51 +0,0 @@ - [ - 'slug' => Specification::S_05VCPU_512MB, - 'memory' => 512, - 'cpus' => 0.5 - ], - Specification::S_1VCPU_512MB => [ - 'slug' => Specification::S_1VCPU_512MB, - 'memory' => 512, - 'cpus' => 1 - ], - Specification::S_1VCPU_1GB => [ - 'slug' => Specification::S_1VCPU_1GB, - 'memory' => 1024, - 'cpus' => 1 - ], - Specification::S_2VCPU_2GB => [ - 'slug' => Specification::S_2VCPU_2GB, - 'memory' => 2048, - 'cpus' => 2 - ], - Specification::S_2VCPU_4GB => [ - 'slug' => Specification::S_2VCPU_4GB, - 'memory' => 4096, - 'cpus' => 2 - ], - Specification::S_4VCPU_4GB => [ - 'slug' => Specification::S_4VCPU_4GB, - 'memory' => 4096, - 'cpus' => 4 - ], - Specification::S_4VCPU_8GB => [ - 'slug' => Specification::S_4VCPU_8GB, - 'memory' => 8192, - 'cpus' => 4 - ], - Specification::S_8VCPU_4GB => [ - 'slug' => Specification::S_8VCPU_4GB, - 'memory' => 4096, - 'cpus' => 8 - ], - Specification::S_8VCPU_8GB => [ - 'slug' => Specification::S_8VCPU_8GB, - 'memory' => 8192, - 'cpus' => 8 - ] -]; diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 88e1e2ae7b..0942944547 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -183,7 +183,13 @@ App::post('/v1/functions') ->param('templateVersion', '', new Text(128, 0), 'Version (tag) for the repo linked to the function template.', true) ->param('specification', APP_FUNCTION_SPECIFICATION_DEFAULT, fn (array $plan) => new RuntimeSpecification( $plan, - Config::getParam('runtime-specifications', []), + Config::getParam('runtime-specifications', [ + APP_FUNCTION_SPECIFICATION_DEFAULT => [ + 'slug ' => APP_FUNCTION_SPECIFICATION_DEFAULT, + 'memory' => APP_FUNCTION_MEMORY_DEFAULT, + 'cpus' => APP_FUNCTION_CPUS_DEFAULT + ] + ]), App::getEnv('_APP_FUNCTIONS_CPUS', APP_FUNCTION_CPUS_DEFAULT), App::getEnv('_APP_FUNCTIONS_MEMORY', APP_FUNCTION_MEMORY_DEFAULT) ), 'Runtime specification for the function and builds.', true, ['plan']) @@ -857,7 +863,13 @@ App::put('/v1/functions/:functionId') ->param('providerRootDirectory', '', new Text(128, 0), 'Path to function code in the linked repo.', true) ->param('specification', APP_FUNCTION_SPECIFICATION_DEFAULT, fn (array $plan) => new RuntimeSpecification( $plan, - Config::getParam('runtime-specifications', []), + Config::getParam('runtime-specifications', [ + APP_FUNCTION_SPECIFICATION_DEFAULT => [ + 'slug ' => APP_FUNCTION_SPECIFICATION_DEFAULT, + 'memory' => APP_FUNCTION_MEMORY_DEFAULT, + 'cpus' => APP_FUNCTION_CPUS_DEFAULT + ] + ]), App::getEnv('_APP_FUNCTIONS_CPUS', APP_FUNCTION_CPUS_DEFAULT), App::getEnv('_APP_FUNCTIONS_MEMORY', APP_FUNCTION_MEMORY_DEFAULT) ), 'Runtime specification for the function and builds.', true, ['plan']) @@ -968,8 +980,6 @@ App::put('/v1/functions/:functionId') $live = false; } - $spec = Config::getParam('runtime-specifications')[$specification] ?? []; - // Enforce Cold Start if spec limits change. if ($function->getAttribute('specification') !== $specification && !empty($function->getAttribute('deployment'))) { $executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST')); @@ -1883,11 +1893,12 @@ App::post('/v1/functions/:functionId/executions') ->inject('dbForProject') ->inject('dbForPlatform') ->inject('user') + ->inject('specifications') ->inject('queueForEvents') ->inject('queueForStatsUsage') ->inject('queueForFunctions') ->inject('geodb') - ->action(function (string $functionId, string $body, mixed $async, string $path, string $method, mixed $headers, ?string $scheduledAt, Response $response, Request $request, Document $project, Database $dbForProject, Database $dbForPlatform, Document $user, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb) { + ->action(function (string $functionId, string $body, mixed $async, string $path, string $method, mixed $headers, ?string $scheduledAt, Response $response, Request $request, Document $project, Database $dbForProject, Database $dbForPlatform, Document $user, array $specifications, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb) { $async = \strval($async) === 'true' || \strval($async) === '1'; if (!$async && !is_null($scheduledAt)) { @@ -1928,7 +1939,7 @@ App::post('/v1/functions/:functionId/executions') $version = $function->getAttribute('version', 'v2'); $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); - $spec = Config::getParam('runtime-specifications')[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; + $spec = $specifications[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; $runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null; diff --git a/app/controllers/general.php b/app/controllers/general.php index a374aa3c39..db99ebee9b 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -50,7 +50,7 @@ Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); -function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname) +function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, array $specifications) { $utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml'); @@ -185,7 +185,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw $version = $function->getAttribute('version', 'v2'); $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); - $spec = Config::getParam('runtime-specifications')[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; + $spec = $specifications[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; $runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null; @@ -505,7 +505,8 @@ App::init() ->inject('queueForFunctions') ->inject('isResourceBlocked') ->inject('previewHostname') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, callable $isResourceBlocked, string $previewHostname) { + ->inject('specifications') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, callable $isResourceBlocked, string $previewHostname, array $specifications) { /* * Appwrite Router */ @@ -513,7 +514,7 @@ App::init() $mainDomain = System::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain || !empty($previewHostname)) { - if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname)) { + if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $specifications)) { return; } } diff --git a/app/init/configs.php b/app/init/configs.php index 1a5dbced1b..1a0d91450d 100644 --- a/app/init/configs.php +++ b/app/init/configs.php @@ -33,5 +33,4 @@ Config::load('storage-logos', __DIR__ . '/../config/storage/logos.php'); Config::load('storage-mimes', __DIR__ . '/../config/storage/mimes.php'); Config::load('storage-inputs', __DIR__ . '/../config/storage/inputs.php'); Config::load('storage-outputs', __DIR__ . '/../config/storage/outputs.php'); -Config::load('runtime-specifications', __DIR__ . '/../config/runtimes/specifications.php'); Config::load('function-templates', __DIR__ . '/../config/function-templates.php'); diff --git a/app/init/resources.php b/app/init/resources.php index 4e53b24c06..ade8add130 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -822,3 +822,13 @@ App::setResource('apiKey', function (Request $request, Document $project): ?Key return Key::decode($project, $key); }, ['request', 'project']); + +App::setResource('specifications', function () { + return Config::getParam('runtime-specifications', [ + APP_FUNCTION_SPECIFICATION_DEFAULT => [ + 'slug ' => APP_FUNCTION_SPECIFICATION_DEFAULT, + 'memory' => APP_FUNCTION_MEMORY_DEFAULT, + 'cpus' => APP_FUNCTION_CPUS_DEFAULT + ] + ]); +}); diff --git a/src/Appwrite/Platform/Workers/Builds.php b/src/Appwrite/Platform/Workers/Builds.php index 6f26e9a80c..3c83950e71 100644 --- a/src/Appwrite/Platform/Workers/Builds.php +++ b/src/Appwrite/Platform/Workers/Builds.php @@ -59,8 +59,9 @@ class Builds extends Action ->inject('deviceForFunctions') ->inject('isResourceBlocked') ->inject('log') - ->callback(fn ($message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log) => - $this->action($message, $project, $dbForPlatform, $queueForEvents, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $usage, $cache, $dbForProject, $deviceForFunctions, $isResourceBlocked, $log)); + ->inject('specifications') + ->callback(fn ($message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log, $specifications) => + $this->action($message, $project, $dbForPlatform, $queueForEvents, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $usage, $cache, $dbForProject, $deviceForFunctions, $isResourceBlocked, $log, $specifications)); } /** @@ -79,7 +80,7 @@ class Builds extends Action * @return void * @throws \Utopia\Database\Exception */ - public function action(Message $message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $queueForStatsUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log): void + public function action(Message $message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $queueForStatsUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log, $specifications): void { $payload = $message->getPayload() ?? []; @@ -100,7 +101,7 @@ class Builds extends Action case BUILD_TYPE_RETRY: Console::info('Creating build for deployment: ' . $deployment->getId()); $github = new GitHub($cache); - $this->buildDeployment($deviceForFunctions, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $queueForEvents, $queueForStatsUsage, $dbForPlatform, $dbForProject, $github, $project, $resource, $deployment, $template, $isResourceBlocked, $log); + $this->buildDeployment($deviceForFunctions, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $queueForEvents, $queueForStatsUsage, $dbForPlatform, $dbForProject, $github, $project, $resource, $deployment, $template, $isResourceBlocked, $log, $specifications); break; default: @@ -127,7 +128,7 @@ class Builds extends Action * @throws \Utopia\Database\Exception * @throws Exception */ - protected function buildDeployment(Device $deviceForFunctions, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Database $dbForPlatform, Database $dbForProject, GitHub $github, Document $project, Document $function, Document $deployment, Document $template, callable $isResourceBlocked, Log $log): void + protected function buildDeployment(Device $deviceForFunctions, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Database $dbForPlatform, Database $dbForProject, GitHub $github, Document $project, Document $function, Document $deployment, Document $template, callable $isResourceBlocked, Log $log, array $specifications): void { $executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST')); @@ -156,7 +157,7 @@ class Builds extends Action } $version = $function->getAttribute('version', 'v2'); - $spec = Config::getParam('runtime-specifications')[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; + $spec = $specifications[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); $key = $function->getAttribute('runtime'); $runtime = $runtimes[$key] ?? null; diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index a7caa3207f..9109ec0c4a 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -52,10 +52,11 @@ class Functions extends Action ->inject('queueForStatsUsage') ->inject('log') ->inject('isResourceBlocked') - ->callback(fn (Document $project, Message $message, Database $dbForProject, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Log $log, callable $isResourceBlocked) => $this->action($project, $message, $dbForProject, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $queueForEvents, $queueForStatsUsage, $log, $isResourceBlocked)); + ->inject('specifications') + ->callback(fn (Document $project, Message $message, Database $dbForProject, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Log $log, callable $isResourceBlocked, $specifications) => $this->action($project, $message, $dbForProject, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $queueForEvents, $queueForStatsUsage, $log, $isResourceBlocked, $specifications)); } - public function action(Document $project, Message $message, Database $dbForProject, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Log $log, callable $isResourceBlocked): void + public function action(Document $project, Message $message, Database $dbForProject, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Log $log, callable $isResourceBlocked, array $specifications): void { $payload = $message->getPayload() ?? []; @@ -153,6 +154,7 @@ class Functions extends Action 'user-agent' => 'Appwrite/' . APP_VERSION_STABLE, 'content-type' => 'application/json' ], + specifications: $specifications, data: null, user: $user, jwt: null, @@ -192,6 +194,7 @@ class Functions extends Action path: $path, method: $method, headers: $headers, + specifications: $specifications, data: $data, user: $user, jwt: $jwt, @@ -216,6 +219,7 @@ class Functions extends Action path: $path, method: $method, headers: $headers, + specifications: $specifications, data: $data, user: $user, jwt: $jwt, @@ -302,6 +306,7 @@ class Functions extends Action * @param string $path * @param string $method * @param array $headers + * @param array $specifications * @param string|null $data * @param Document|null $user * @param string|null $jwt @@ -328,6 +333,7 @@ class Functions extends Action string $path, string $method, array $headers, + array $specifications, string $data = null, ?Document $user = null, string $jwt = null, @@ -338,7 +344,7 @@ class Functions extends Action $user ??= new Document(); $functionId = $function->getId(); $deploymentId = $function->getAttribute('deployment', ''); - $spec = Config::getParam('runtime-specifications')[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; + $spec = $specifications[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; $log->addTag('deploymentId', $deploymentId);