1
0
Fork 0
mirror of synced 2024-06-02 19:04:49 +12:00

feat: use coroutines for deleting within the executor

This commit is contained in:
Christy Jacob 2022-01-28 05:21:11 +04:00
parent dbcf479cd9
commit 5125adc16b
2 changed files with 73 additions and 36 deletions

View file

@ -947,58 +947,62 @@ App::post('/v1/functions/:functionId/executions')
App::delete('/v1/functions/:functionId')
->desc('Delete a function')
->param('functionId', '', new UID())
->inject('projectId')
->inject('response')
->inject('dbForProject')
->action(
function (string $functionId, Response $response, Database $dbForProject) use ($orchestrationPool) {
try {
/** @var Orchestration $orchestration */
$orchestration = $orchestrationPool->get();
function (string $functionId, string $projectId, Response $response, Database $dbForProject) use ($orchestrationPool) {
// Get function document
$function = $dbForProject->getDocument('functions', $functionId);
$results = $dbForProject->find('deployments', [new Query('functionId', Query::TYPE_EQUAL, [$functionId])], 999);
// Check if function exists
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
// If amount is 0 then we simply return true
if (count($results) === 0) {
$response
->setStatusCode(Response::STATUS_CODE_OK)
->send();
}
$results = $dbForProject->find('deployments', [new Query('functionId', Query::TYPE_EQUAL, [$functionId])], 999);
Console::info("Deleting $results count");
// If amount is 0 then we simply return true
if (count($results) === 0) {
return $response->json(['success' => true]);
}
// Delete the containers of all deployments
foreach ($results as $deployment) {
// Delete the containers of all deployments
// TODO : @christy Delete all build containers as well. Not just the latest one,
global $register;
foreach ($results as $deployment) {
go(function () use ($orchestrationPool, $deployment, $register, $projectId) {
try {
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
$cache = new Cache(new RedisCache($redis));
$dbForProject = new Database(new MariaDB($db), $cache);
$dbForProject->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
$dbForProject->setNamespace('_project_' . $projectId);
$orchestration = $orchestrationPool->get();
// Remove any ongoing builds
if ($deployment->getAttribute('buildId')) {
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId'));
if ($build->getAttribute('status') === 'building') {
// Remove the build
$orchestration->remove('build-stage-' . $deployment->getAttribute('buildId'), true);
Console::info('Removed build for deployment ' . $deployment['$id']);
}
}
$orchestration->remove('appwrite-function-' . $deployment['$id'], true);
Console::info('Removed container for deployment ' . $deployment['$id']);
} catch (Exception $e) {
} catch (Throwable $th) {
// Do nothing, we don't care that much if it fails
Console::error($th->getMessage());
} finally {
$orchestrationPool->put($orchestration);
}
}
return $response->json(['success' => true]);
} catch (Exception $e) {
logError($e, "cleanupFunction");
$orchestrationPool->put($orchestration);
return $response->json(['error' => $e->getMessage()]);
});
}
$orchestrationPool->put($orchestration);
$response
->setStatusCode(Response::STATUS_CODE_OK)
->send();
}
);

View file

@ -8,6 +8,7 @@ use Appwrite\Resque\Worker;
use Utopia\Storage\Device\Local;
use Utopia\Abuse\Abuse;
use Utopia\Abuse\Adapters\TimeLimit;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Audit\Audit;
@ -310,10 +311,41 @@ class DeletesV1 extends Worker
protected function deleteFunction(Document $document, string $projectId): void
{
$dbForProject = $this->getProjectDB($projectId);
$storageFunctions = new Local(APP_STORAGE_FUNCTIONS . '/app-' . $projectId);
$storageBuilds = new Local(APP_STORAGE_BUILDS . '/app-' . $projectId);
// Delete Deployments
/**
* Request executor to delete all deployment containers
*/
try {
$ch = \curl_init();
\curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/functions/{$document->getId()}");
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'x-appwrite-project: '. $projectId,
'x-appwrite-executor-key: '. App::getEnv('_APP_EXECUTOR_SECRET', '')
]);
$executorResponse = \curl_exec($ch);
$error = \curl_error($ch);
if (!empty($error)) {
throw new Exception($error, 500);
}
$statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($statusCode >= 400) {
throw new Exception('Executor error: ' . $executorResponse, $statusCode);
}
\curl_close($ch);
} catch (Throwable $th) {
Console::error($th->getMessage());
}
/**
* Delete Deployments
*/
$storageFunctions = new Local(APP_STORAGE_FUNCTIONS . '/app-' . $projectId);
$deploymentIds = [];
$this->deleteByGroup('deployments', [
new Query('functionId', Query::TYPE_EQUAL, [$document->getId()])
@ -326,7 +358,10 @@ class DeletesV1 extends Worker
}
});
// Delete builds
/**
* Delete builds
*/
$storageBuilds = new Local(APP_STORAGE_BUILDS . '/app-' . $projectId);
$this->deleteByGroup('builds', [
new Query('deploymentId', Query::TYPE_EQUAL, $deploymentIds)
], $dbForProject, function (Document $document) use ($storageBuilds) {
@ -342,8 +377,6 @@ class DeletesV1 extends Worker
new Query('functionId', Query::TYPE_EQUAL, [$document->getId()])
], $dbForProject);
// Send delete request to executor
}