diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index f7de8362a2..ddfd0619be 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -997,6 +997,9 @@ App::post('/v1/functions/:functionId/executions') $execution->setAttribute('stderr', $executionResponse['stderr']); $execution->setAttribute('time', $executionResponse['time']); } catch (\Throwable $th) { + $endtime = \microtime(true); + $time = $endtime - $execution->getAttribute('dateCreated'); + $execution->setAttribute('time', $time); $execution->setAttribute('status', 'failed'); $execution->setAttribute('statusCode', $th->getCode()); $execution->setAttribute('stderr', $th->getMessage()); diff --git a/app/executor.php b/app/executor.php index 9d77d3f4f7..5ddbf88b60 100644 --- a/app/executor.php +++ b/app/executor.php @@ -244,7 +244,7 @@ App::post('/v1/runtimes') command: $commands, stdout: $stdout, stderr: $stderr, - timeout: App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900) + timeout: App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900) ); if (!$status) { @@ -467,45 +467,33 @@ App::post('/v1/execution') \curl_close($ch); - // If timeout error - if (in_array($errNo, [CURLE_OPERATION_TIMEDOUT, 110])) { - $statusCode = 124; + switch (true) { + /** No Error. */ + case $errNo === 0: + break; + /** Runtime not ready for requests yet. 111 is the swoole error code for Connection Refused - see https://openswoole.com/docs/swoole-error-code */ + case $errNo === 111: + throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 406); + /** Any other CURL error */ + default: + throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 500); } - - // 110 is the Swoole error code for timeout, see: https://www.swoole.co.uk/docs/swoole-error-code - if ($errNo !== 0 && $errNo !== CURLE_COULDNT_CONNECT && $errNo !== CURLE_OPERATION_TIMEDOUT && $errNo !== 110) { - throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 406); + + switch (true) { + case $statusCode >= 500: + $stderr = $executorResponse ?? 'Internal Runtime error.'; + break; + case $statusCode >= 100: + $stdout = $executorResponse; + break; + default: + $stderr = $executorResponse ?? 'Execution failed.'; + break; } - - $executionData = []; - - if (!empty($executorResponse)) { - $executionData = json_decode($executorResponse, true); - } - - if (isset($executionData['code'])) { - $statusCode = $executionData['code']; - } - - if ($statusCode === 500) { - if (isset($executionData['message'])) { - $stderr = $executionData['message']; - } else { - $stderr = 'Internal Runtime error'; - } - } else if ($statusCode === 124) { - $stderr = 'Execution timed out.'; - } else if ($statusCode === 0) { - $stderr = 'Execution failed.'; - } else if ($statusCode >= 200 && $statusCode < 300) { - $stdout = $executorResponse; - } else { - $stderr = 'Execution failed.'; - } - + $executionEnd = \microtime(true); $executionTime = ($executionEnd - $executionStart); - $functionStatus = ($statusCode >= 200 && $statusCode < 300) ? 'completed' : 'failed'; + $functionStatus = ($statusCode >= 500) ? 'failed' : 'completed'; Console::success('Function executed in ' . $executionTime . ' seconds, status: ' . $functionStatus); diff --git a/app/tasks/maintenance.php b/app/tasks/maintenance.php index 3bb528c4d9..6ba744fde0 100644 --- a/app/tasks/maintenance.php +++ b/app/tasks/maintenance.php @@ -27,6 +27,11 @@ function getConsoleDB(): Database $database = new Database(new MariaDB($register->get('db')), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_console'); // Main DB + + if (!$database->exists($database->getDefaultDatabase(), '_metadata')) { + throw new \Exception('Console project not ready'); + } + break; // leave loop if successful } catch (\Exception $e) { Console::warning("Database not ready. Retrying connection ({$attempts})..."); diff --git a/app/workers/functions.php b/app/workers/functions.php index 1a6ae838b1..b621d95f43 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -295,7 +295,10 @@ class FunctionsV1 extends Worker ->setAttribute('stderr', $executionResponse['stderr']) ->setAttribute('time', $executionResponse['time']); } catch (\Throwable $th) { + $endtime = \microtime(true); + $time = $endtime - $execution->getAttribute('dateCreated'); $execution + ->setAttribute('time', $time) ->setAttribute('status', 'failed') ->setAttribute('statusCode', $th->getCode()) ->setAttribute('stderr', $th->getMessage()); diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index 9682688736..88489b5412 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -209,7 +209,7 @@ abstract class Worker throw new \Exception("Project does not exist: {$projectId}"); } - if ($type === self::DATABASE_CONSOLE && !$database->exists($database->getDefaultDatabase(), 'realtime')) { + if ($type === self::DATABASE_CONSOLE && !$database->exists($database->getDefaultDatabase(), '_metadata')) { throw new \Exception('Console project not ready'); } diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index a766b269ed..312fdc860c 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -748,7 +748,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(201, $execution['headers']['status-code']); - sleep(5); + sleep(10); $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', @@ -762,11 +762,11 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['$id'], $executionId); $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); $this->assertEquals($executions['body']['executions'][0]['status'], 'failed'); - $this->assertEquals($executions['body']['executions'][0]['statusCode'], 124); + $this->assertEquals($executions['body']['executions'][0]['statusCode'], 500); $this->assertGreaterThan(2, $executions['body']['executions'][0]['time']); - $this->assertLessThan(3, $executions['body']['executions'][0]['time']); + $this->assertLessThan(6, $executions['body']['executions'][0]['time']); $this->assertEquals($executions['body']['executions'][0]['response'], ''); - $this->assertEquals($executions['body']['executions'][0]['stderr'], 'Execution timed out.'); + $this->assertEquals($executions['body']['executions'][0]['stderr'], 'An internal curl error has occurred within the executor! Error Msg: Operation timed out'); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [