1
0
Fork 0
mirror of synced 2024-06-27 02:31:04 +12:00

feat: sync master and fix tests

This commit is contained in:
Christy Jacob 2022-01-27 02:29:49 +04:00
parent c595f4eea9
commit f65b3e0c5b
4 changed files with 87 additions and 103 deletions

View file

@ -314,7 +314,7 @@ function createRuntimeServer(string $functionId, string $projectId, string $depl
Console::success('Runtime Server created in ' . ($executionEnd - $executionStart) . ' seconds');
} else {
Console::info('Runtime server is ready to run');
Console::success('Runtime server is ready to run');
}
} catch (\Throwable $th) {
var_dump($th->getTraceAsString());
@ -943,6 +943,7 @@ App::post('/v1/functions/:functionId/executions')
);
App::delete('/v1/functions/:functionId')
->desc('Delete a function')
->param('functionId', '', new UID())
->inject('response')
->inject('dbForProject')
@ -1005,7 +1006,7 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/runtime')
->param('deploymentId', '', new UID(), 'Deployment unique ID.')
->inject('response')
->inject('dbForProject')
->inject('projectID')
->inject('projectId')
->action(function (string $functionId, string $deploymentId, Response $response, Database $dbForProject, string $projectID) use ($runtimes) {
// Get function document
$function = $dbForProject->getDocument('functions', $functionId);
@ -1032,6 +1033,7 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/runtime')
});
App::delete('/v1/deployments/:deploymentId')
->desc('Delete a deployment')
->param('deploymentId', '', new UID(), 'Deployment unique ID.')
->inject('response')
->inject('dbForProject')
@ -1077,41 +1079,81 @@ App::delete('/v1/deployments/:deploymentId')
return $response->json(['success' => true]);
});
App::post('/v1/builds/:buildId')
App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
->desc("Create a new build")
->param('functionId', '', new UID(), 'Function unique ID.', false)
->param('deploymentId', '', new UID(), 'Deployment unique ID.', false)
->param('buildId', '', new UID(), 'Build unique ID.', false)
->inject('response')
->inject('dbForProject')
->inject('projectID')
->action(function (string $buildId, Response $response, Database $dbForProject, string $projectID) {
try {
// Get build document
->inject('projectId')
->action(function (string $functionId, string $deploymentId, string $buildId, Response $response, Database $dbForProject, string $projectId) {
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404);
}
$build = $dbForProject->getDocument('builds', $buildId);
if ($build->isEmpty()) {
throw new Exception('Build not found', 404);
}
if ($build->getAttribute('status') === 'running') {
throw new Exception('Build is already running', 409);
}
// Check if build is already finished
if ($build->getAttribute('status') === 'finished') {
throw new Exception('Build is already finished', 409);
}
go(function() use ($functionId, $deploymentId, $buildId, $projectId, $dbForProject, $function, $deployment) {
Console::info('Starting build for deployment ' . $deployment['$id']);
runBuildStage($buildId, $projectId);
// Update the schedule
$schedule = $function->getAttribute('schedule', '');
$cron = (empty($function->getAttribute('deployment')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (empty($function->getAttribute('deployment')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
// Grab build
$build = $dbForProject->getDocument('builds', $buildId);
// Check if build exists
if ($build->isEmpty()) {
throw new Exception('Build not found', 404);
// If the build failed, it won't be possible to deploy
if ($build->getAttribute('status') !== 'ready') {
throw new Exception('Build failed', 500);
}
// Check if build is already running
if ($build->getAttribute('status') === 'running') {
throw new Exception('Build is already running', 409);
if ($deployment->getAttribute('deploy') === true) {
// Update the function document setting the deployment as the active one
$function
->setAttribute('deployment', $deployment->getId())
->setAttribute('scheduleNext', (int)$next);
$function = $dbForProject->updateDocument('functions', $functionId, $function);
}
// Check if build is already finished
if ($build->getAttribute('status') === 'finished') {
throw new Exception('Build is already finished', 409);
// Deploy Runtime Server
try {
Console::info("[ INFO ] Creating runtime server");
createRuntimeServer($functionId, $projectId, $deploymentId, $dbForProject);
} catch (\Throwable $th) {
Console::error($th->getMessage());
$deployment->setAttribute('status', 'failed');
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
throw $th;
}
runBuildStage($buildId, $projectID, $dbForProject);
});
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->send();
} catch (Exception $e) {
// TODO : @matej,why do we need to log here ? There is a global error handler that logs errors
logError($e, "buildEndpoint");
throw $e;
}
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->send();
});
App::setMode(App::MODE_TYPE_PRODUCTION); // Define Mode
@ -1276,7 +1318,7 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
);
}, ['error', 'utopia', 'request', 'response']);
App::setResource('projectID', function () use ($projectId) {
App::setResource('projectId', function () use ($projectId) {
return $projectId;
});

View file

@ -22,7 +22,7 @@ use Utopia\Logger\Log\User;
$http = new Server("0.0.0.0", App::getEnv('PORT', 80));
$http->set([
'worker_num' => 1,
'worker_num' => 4,
'reactor_num' => 6
]);

View file

@ -43,8 +43,10 @@ class BuildsV1 extends Worker
case BUILD_TYPE_RETRY:
$buildId = $this->args['buildId'] ?? '';
$functionId = $this->args['functionId'] ?? '';
$deploymentId = $this->args['deploymentId'] ?? '';
Console::info("[ INFO ] Retrying build for id: $buildId");
$this->triggerBuild($projectId, $buildId);
$this->createBuild($projectId, $functionId, $deploymentId, $buildId);
break;
default:
@ -53,40 +55,11 @@ class BuildsV1 extends Worker
}
}
protected function triggerBuild(string $projectId, string $buildId)
protected function createBuild(string $projectId, string $functionId, string $deploymentId, string $buildId)
{
// TODO: What is a reasonable time to wait for a build to complete?
$ch = \curl_init();
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/builds/$buildId");
\curl_setopt($ch, CURLOPT_POST, true);
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, CURLOPT_TIMEOUT, 900);
\curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
\curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'x-appwrite-project: '.$projectId,
'x-appwrite-executor-key: '. App::getEnv('_APP_EXECUTOR_SECRET', '')
]);
$response = \curl_exec($ch);
$responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = \curl_error($ch);
if (!empty($error)) {
throw new \Exception($error);
}
\curl_close($ch);
if ($responseStatus >= 400) {
throw new \Exception("Build failed with status code: $responseStatus");
}
}
protected function triggerCreateRuntimeServer(string $projectId, string $functionId, string $deploymentId)
{
$ch = \curl_init();
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/functions/$functionId/deployments/$deploymentId/runtime");
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/functions/$functionId/deployments/$deploymentId/builds/$buildId");
\curl_setopt($ch, CURLOPT_POST, true);
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, CURLOPT_TIMEOUT, 900);
@ -117,7 +90,6 @@ class BuildsV1 extends Worker
$dbForProject = $this->getProjectDB($projectId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
@ -142,7 +114,6 @@ class BuildsV1 extends Worker
try {
$buildId = $dbForProject->getId();
// TODO : There is no way to associate a build with a deployment. So we need to add a deploymentId attribute to the build document
// TODO : What should be the read and write permissions for a build ?
$dbForProject->createDocument('builds', new Document([
'$id' => $buildId,
'$read' => [],
@ -170,11 +141,11 @@ class BuildsV1 extends Worker
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
} catch (\Throwable $th) {
Console::error($th->getMessage());
$deployment->setAttribute('status', 'failed');
$deployment->setAttribute('buildId', '');
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
return;
Console::error($th->getMessage());
throw $th;
}
}
@ -183,50 +154,15 @@ class BuildsV1 extends Worker
Console::info("[ INFO ] Creating build with id: $buildId");
$deployment->setAttribute('status', 'building');
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
$this->triggerBuild($projectId, $buildId);
$this->createBuild($projectId, $functionId, $deploymentId, $buildId);
} catch (\Throwable $th) {
Console::error($th->getMessage());
$deployment->setAttribute('status', 'failed');
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
return;
}
Console::success("[ SUCCESS ] Build id: $buildId completed");
// Update the schedule
$schedule = $function->getAttribute('schedule', '');
$cron = (empty($function->getAttribute('deployment')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (empty($function->getAttribute('deployment')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
// Grab build
$build = $dbForProject->getDocument('builds', $buildId);
// If the build failed, it won't be possible to deploy
if ($build->getAttribute('status') !== 'ready') {
throw new Exception('Build failed', 500);
}
if ($deployment->getAttribute('deploy') === true) {
// Update the function document setting the deployment as the active one
$function
->setAttribute('deployment', $deployment->getId())
->setAttribute('scheduleNext', (int)$next);
$function = $dbForProject->updateDocument('functions', $functionId, $function);
}
// Deploy Runtime Server
try {
Console::info("[ INFO ] Creating runtime server");
$this->triggerCreateRuntimeServer($projectId, $functionId, $deploymentId, $dbForProject);
} catch (\Throwable $th) {
Console::error($th->getMessage());
$deployment->setAttribute('status', 'failed');
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
return;
throw $th;
}
Console::success("[ SUCCESS ] Runtime Server created");
Console::success("[ SUCCESS ] Build id: $buildId started");
}
public function shutdown(): void {}

View file

@ -378,8 +378,14 @@ services:
appwrite-executor:
container_name: appwrite-executor
entrypoint: executor
entrypoint:
- php
- -e
- /usr/src/code/app/executor.php
- -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
stop_signal: SIGINT
ports:
- "8080:8080"
build:
context: .
args: