appwrite/app/worker.php

589 lines
21 KiB
PHP
Raw Normal View History

2022-11-09 17:01:43 +00:00
<?php
require_once __DIR__ . '/init.php';
2024-11-20 10:10:57 +00:00
use Appwrite\Certificates\LetsEncrypt;
2024-10-08 07:54:40 +00:00
use Appwrite\Event\Audit;
use Appwrite\Event\Build;
use Appwrite\Event\Certificate;
use Appwrite\Event\Database as EventDatabase;
use Appwrite\Event\Delete;
use Appwrite\Event\Event;
2026-02-09 19:24:57 +00:00
use Appwrite\Event\Execution;
2024-10-08 07:54:40 +00:00
use Appwrite\Event\Func;
use Appwrite\Event\Mail;
use Appwrite\Event\Messaging;
use Appwrite\Event\Migration;
use Appwrite\Event\Realtime;
2026-01-08 15:51:04 +00:00
use Appwrite\Event\Screenshot;
2025-01-30 04:53:53 +00:00
use Appwrite\Event\StatsUsage;
use Appwrite\Event\Webhook;
2023-05-29 13:58:45 +00:00
use Appwrite\Platform\Appwrite;
2025-11-05 01:41:15 +00:00
use Appwrite\Utopia\Database\Documents\User;
use Executor\Executor;
2022-11-09 17:01:43 +00:00
use Swoole\Runtime;
2024-12-20 14:44:50 +00:00
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
2025-12-24 01:30:02 +00:00
use Utopia\Audit\Adapter\Database as AdapterDatabase;
use Utopia\Audit\Audit as UtopiaAudit;
use Utopia\Cache\Adapter\Pool as CachePool;
2024-10-08 07:54:40 +00:00
use Utopia\Cache\Adapter\Sharding;
use Utopia\Cache\Cache;
use Utopia\Config\Config;
use Utopia\Console;
use Utopia\Database\Adapter\Pool as DatabasePool;
2022-11-09 17:01:43 +00:00
use Utopia\Database\Database;
use Utopia\Database\DateTime;
2022-11-12 14:35:42 +00:00
use Utopia\Database\Document;
2023-05-29 13:58:45 +00:00
use Utopia\Database\Validator\Authorization;
2024-10-08 07:54:40 +00:00
use Utopia\DSN\DSN;
2022-11-16 10:40:41 +00:00
use Utopia\Logger\Log;
2022-11-16 13:34:11 +00:00
use Utopia\Logger\Logger;
2024-03-06 17:34:21 +00:00
use Utopia\Platform\Service;
2024-10-08 07:54:40 +00:00
use Utopia\Pools\Group;
use Utopia\Queue\Broker\Pool as BrokerPool;
2024-03-06 17:34:21 +00:00
use Utopia\Queue\Message;
2025-01-29 14:13:58 +00:00
use Utopia\Queue\Publisher;
2024-10-08 07:54:40 +00:00
use Utopia\Queue\Server;
use Utopia\Registry\Registry;
use Utopia\Storage\Device\Telemetry as TelemetryDevice;
2024-04-01 11:02:47 +00:00
use Utopia\System\System;
use Utopia\Telemetry\Adapter as Telemetry;
2025-05-17 10:43:32 +00:00
use Utopia\Telemetry\Adapter\None as NoTelemetry;
2022-11-16 10:40:41 +00:00
Runtime::enableCoroutine();
require_once __DIR__ . '/init/span.php';
2023-06-05 16:13:00 +00:00
global $register;
2024-10-08 07:54:40 +00:00
Server::setResource('register', fn () => $register);
Server::setResource('authorization', function () {
$authorization = new Authorization();
$authorization->disable();
return $authorization;
}, []);
Server::setResource('dbForPlatform', function (Cache $cache, Registry $register, Authorization $authorization) {
2024-10-08 07:54:40 +00:00
$pools = $register->get('pools');
$adapter = new DatabasePool($pools->get('console'));
$dbForPlatform = new Database($adapter, $cache);
$dbForPlatform
->setDatabase(APP_DATABASE)
->setAuthorization($authorization)
->setNamespace('_console')
->setDocumentType('users', User::class)
;
return $dbForPlatform;
}, ['cache', 'register', 'authorization']);
2024-10-08 07:54:40 +00:00
Server::setResource('project', function (Message $message, Database $dbForPlatform) {
2024-10-08 07:54:40 +00:00
$payload = $message->getPayload() ?? [];
$project = new Document($payload['project'] ?? []);
if ($project->getId() === 'console') {
2024-10-08 07:54:40 +00:00
return $project;
}
return $dbForPlatform->getDocument('projects', $project->getId());
}, ['message', 'dbForPlatform']);
2024-10-08 07:54:40 +00:00
Server::setResource('dbForProject', function (Cache $cache, Registry $register, Message $message, Document $project, Database $dbForPlatform, Authorization $authorization) {
2024-10-08 07:54:40 +00:00
if ($project->isEmpty() || $project->getId() === 'console') {
2025-01-13 06:24:58 +00:00
return $dbForPlatform;
2024-10-08 07:54:40 +00:00
}
2025-01-13 06:24:58 +00:00
$pools = $register->get('pools');
2024-10-08 07:54:40 +00:00
try {
$dsn = new DSN($project->getAttribute('database'));
} catch (\InvalidArgumentException) {
// TODO: Temporary until all projects are using shared tables
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
}
$adapter = new DatabasePool($pools->get($dsn->getHost()));
2025-01-13 06:24:58 +00:00
$database = new Database($adapter, $cache);
2025-11-05 01:41:15 +00:00
$database->setDocumentType('users', User::class);
2024-10-08 07:54:40 +00:00
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
if (\in_array($dsn->getHost(), $sharedTables)) {
2024-10-08 07:54:40 +00:00
$database
->setSharedTables(true)
2025-06-16 17:24:48 +00:00
->setTenant((int)$project->getSequence())
2024-10-08 07:54:40 +00:00
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
2025-05-26 05:42:11 +00:00
->setNamespace('_' . $project->getSequence());
2024-10-08 07:54:40 +00:00
}
$database
->setDatabase(APP_DATABASE)
->setAuthorization($authorization)
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
2024-10-08 07:54:40 +00:00
return $database;
}, ['cache', 'register', 'message', 'project', 'dbForPlatform', 'authorization']);
2024-10-08 07:54:40 +00:00
Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache, Authorization $authorization) {
2024-10-08 07:54:40 +00:00
$databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools
return function (Document $project) use ($pools, $dbForPlatform, $cache, $authorization, &$databases): Database {
2024-10-08 07:54:40 +00:00
if ($project->isEmpty() || $project->getId() === 'console') {
return $dbForPlatform;
2024-03-07 13:52:13 +00:00
}
2023-06-05 16:13:00 +00:00
2024-10-08 07:54:40 +00:00
try {
$dsn = new DSN($project->getAttribute('database'));
} catch (\InvalidArgumentException) {
// TODO: Temporary until all projects are using shared tables
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
}
2024-02-20 11:40:55 +00:00
2024-10-08 07:54:40 +00:00
if (isset($databases[$dsn->getHost()])) {
$database = $databases[$dsn->getHost()];
$database->setAuthorization($authorization);
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
if (\in_array($dsn->getHost(), $sharedTables)) {
2024-10-08 07:54:40 +00:00
$database
->setSharedTables(true)
2025-06-16 17:24:48 +00:00
->setTenant((int)$project->getSequence())
2024-10-08 07:54:40 +00:00
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
2025-05-26 05:42:11 +00:00
->setNamespace('_' . $project->getSequence());
2024-10-08 07:54:40 +00:00
}
2024-02-20 11:40:55 +00:00
2024-10-08 07:54:40 +00:00
return $database;
}
2024-02-20 11:40:55 +00:00
$adapter = new DatabasePool($pools->get($dsn->getHost()));
$database = new Database($adapter, $cache);
2024-02-20 11:40:55 +00:00
2024-10-08 07:54:40 +00:00
$databases[$dsn->getHost()] = $database;
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
if (\in_array($dsn->getHost(), $sharedTables)) {
2024-10-08 07:54:40 +00:00
$database
->setSharedTables(true)
2025-06-16 17:24:48 +00:00
->setTenant((int)$project->getSequence())
2024-10-08 07:54:40 +00:00
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
2025-05-26 05:42:11 +00:00
->setNamespace('_' . $project->getSequence());
2024-10-08 07:54:40 +00:00
}
2023-05-29 13:58:45 +00:00
$database
->setDatabase(APP_DATABASE)
->setAuthorization($authorization)
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
2024-10-08 07:54:40 +00:00
return $database;
};
}, ['pools', 'dbForPlatform', 'cache', 'authorization']);
2023-05-29 13:58:45 +00:00
Server::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorization $authorization) {
2025-01-27 02:26:06 +00:00
$database = null;
return function (?Document $project = null) use ($pools, $cache, $database, $authorization) {
2025-01-27 02:26:06 +00:00
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
2025-06-16 17:24:48 +00:00
$database->setTenant((int)$project->getSequence());
2025-01-27 02:26:06 +00:00
return $database;
}
2025-04-17 05:09:08 +00:00
$adapter = new DatabasePool($pools->get('logs'));
$database = new Database($adapter, $cache);
2025-01-27 02:26:06 +00:00
$database
->setDatabase(APP_DATABASE)
->setAuthorization($authorization)
2025-01-27 02:26:06 +00:00
->setSharedTables(true)
->setNamespace('logsV1')
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER)
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES_WORKER);
2025-01-27 02:26:06 +00:00
// set tenant
if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
2025-06-16 17:24:48 +00:00
$database->setTenant((int)$project->getSequence());
2025-01-27 02:26:06 +00:00
}
return $database;
};
}, ['pools', 'cache', 'authorization']);
2025-01-27 02:26:06 +00:00
2024-10-08 07:54:40 +00:00
Server::setResource('abuseRetention', function () {
2025-03-20 13:42:19 +00:00
return time() - (int) System::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', 86400); // 1 day
2024-10-08 07:54:40 +00:00
});
Server::setResource('auditRetention', function (Document $project) {
if ($project->getId() === 'console') {
return DateTime::addSeconds(new \DateTime(), -1 * System::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE', 15778800)); // 6 months
}
return DateTime::addSeconds(new \DateTime(), -1 * System::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', 1209600)); // 14 days
}, ['project']);
2024-10-08 07:54:40 +00:00
Server::setResource('executionRetention', function () {
2025-03-20 13:42:19 +00:00
return DateTime::addSeconds(new \DateTime(), -1 * System::getEnv('_APP_MAINTENANCE_RETENTION_EXECUTION', 1209600)); // 14 days
2024-10-08 07:54:40 +00:00
});
Server::setResource('cache', function (Registry $register) {
$pools = $register->get('pools');
$list = Config::getParam('pools-cache', []);
$adapters = [];
foreach ($list as $value) {
$adapters[] = new CachePool($pools->get($value));
2024-10-08 07:54:40 +00:00
}
return new Cache(new Sharding($adapters));
}, ['register']);
2024-12-20 14:44:50 +00:00
Server::setResource('redis', function () {
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
$port = System::getEnv('_APP_REDIS_PORT', 6379);
$pass = System::getEnv('_APP_REDIS_PASS', '');
$redis = new \Redis();
@$redis->pconnect($host, (int)$port);
if ($pass) {
$redis->auth($pass);
}
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
return $redis;
});
Server::setResource('timelimit', function (\Redis $redis) {
return function (string $key, int $limit, int $time) use ($redis) {
return new TimeLimitRedis($key, $limit, $time, $redis);
};
}, ['redis']);
2024-10-08 07:54:40 +00:00
Server::setResource('log', fn () => new Log());
2025-01-29 14:13:58 +00:00
Server::setResource('publisher', function (Group $pools) {
return new BrokerPool(publisher: $pools->get('publisher'));
2025-01-29 14:13:58 +00:00
}, ['pools']);
2024-10-08 07:54:40 +00:00
2025-07-16 17:11:04 +00:00
Server::setResource('publisherDatabases', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
Server::setResource('publisherFunctions', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
2025-07-16 17:11:04 +00:00
Server::setResource('publisherMigrations', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
Server::setResource('publisherStatsUsage', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
2025-07-03 18:09:08 +00:00
Server::setResource('publisherMessaging', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
2025-01-29 14:13:58 +00:00
Server::setResource('consumer', function (Group $pools) {
return new BrokerPool(consumer: $pools->get('consumer'));
2024-10-08 07:54:40 +00:00
}, ['pools']);
2025-07-16 17:11:04 +00:00
Server::setResource('consumerDatabases', function (BrokerPool $consumer) {
return $consumer;
}, ['consumer']);
Server::setResource('consumerMigrations', function (BrokerPool $consumer) {
return $consumer;
}, ['consumer']);
Server::setResource('consumerStatsUsage', function (BrokerPool $consumer) {
return $consumer;
}, ['consumer']);
2025-07-03 18:09:08 +00:00
Server::setResource('queueForStatsUsage', function (Publisher $publisher) {
return new StatsUsage($publisher);
}, ['publisher']);
2025-01-29 14:13:58 +00:00
Server::setResource('queueForDatabase', function (Publisher $publisher) {
return new EventDatabase($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
2025-01-29 14:13:58 +00:00
Server::setResource('queueForMessaging', function (Publisher $publisher) {
return new Messaging($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
2025-01-29 14:13:58 +00:00
Server::setResource('queueForMails', function (Publisher $publisher) {
return new Mail($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
2025-01-29 14:13:58 +00:00
Server::setResource('queueForBuilds', function (Publisher $publisher) {
return new Build($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
2026-01-08 15:51:04 +00:00
Server::setResource('queueForScreenshots', function (Publisher $publisher) {
return new Screenshot($publisher);
}, ['publisher']);
2025-01-29 14:13:58 +00:00
Server::setResource('queueForDeletes', function (Publisher $publisher) {
return new Delete($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
2025-01-29 14:13:58 +00:00
Server::setResource('queueForEvents', function (Publisher $publisher) {
return new Event($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
2025-01-29 14:13:58 +00:00
Server::setResource('queueForAudits', function (Publisher $publisher) {
return new Audit($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
Server::setResource('queueForWebhooks', function (Publisher $publisher) {
return new Webhook($publisher);
}, ['publisher']);
2025-01-29 14:13:58 +00:00
Server::setResource('queueForFunctions', function (Publisher $publisher) {
return new Func($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
2026-02-09 19:24:57 +00:00
Server::setResource('queueForExecutions', function (Publisher $publisher) {
return new Execution($publisher);
}, ['publisher']);
Server::setResource('queueForRealtime', function () {
return new Realtime();
}, []);
2025-01-29 14:13:58 +00:00
Server::setResource('queueForCertificates', function (Publisher $publisher) {
return new Certificate($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
2025-01-29 14:13:58 +00:00
Server::setResource('queueForMigrations', function (Publisher $publisher) {
return new Migration($publisher);
}, ['publisher']);
2024-10-08 07:54:40 +00:00
Server::setResource('logger', function (Registry $register) {
return $register->get('logger');
}, ['register']);
Server::setResource('pools', function (Registry $register) {
return $register->get('pools');
}, ['register']);
2025-05-18 09:20:08 +00:00
Server::setResource('telemetry', fn () => new NoTelemetry());
Server::setResource('deviceForSites', function (Document $project, Telemetry $telemetry) {
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_SITES . '/app-' . $project->getId()));
}, ['project', 'telemetry']);
2025-04-09 11:05:27 +00:00
2025-08-05 12:40:39 +00:00
Server::setResource('deviceForMigrations', function (Document $project, Telemetry $telemetry) {
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_IMPORTS . '/app-' . $project->getId()));
}, ['project', 'telemetry']);
2024-10-08 07:54:40 +00:00
Server::setResource('deviceForFunctions', function (Document $project, Telemetry $telemetry) {
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId()));
}, ['project', 'telemetry']);
2024-10-08 07:54:40 +00:00
Server::setResource('deviceForFiles', function (Document $project, Telemetry $telemetry) {
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId()));
}, ['project', 'telemetry']);
2024-10-08 07:54:40 +00:00
Server::setResource('deviceForBuilds', function (Document $project, Telemetry $telemetry) {
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId()));
}, ['project', 'telemetry']);
2024-10-08 07:54:40 +00:00
Server::setResource('deviceForCache', function (Document $project, Telemetry $telemetry) {
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_CACHE . '/app-' . $project->getId()));
}, ['project', 'telemetry']);
2024-10-08 07:54:40 +00:00
Server::setResource(
'isResourceBlocked',
fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false
);
2025-05-14 03:38:51 +00:00
Server::setResource('plan', function (array $plan = []) {
return [];
});
2024-11-20 10:10:57 +00:00
Server::setResource('certificates', function () {
$email = System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'));
if (empty($email)) {
throw new Exception('You must set a valid security email address (_APP_EMAIL_CERTIFICATES) to issue a LetsEncrypt SSL certificate.');
}
return new LetsEncrypt($email);
});
2024-11-13 01:29:43 +00:00
Server::setResource('logError', function (Registry $register, Document $project) {
2025-04-01 05:08:58 +00:00
return function (Throwable $error, string $namespace, string $action, ?array $extras = null) use ($register, $project) {
2024-11-13 01:29:43 +00:00
$logger = $register->get('logger');
if ($logger) {
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
$log = new Log();
$log->setNamespace($namespace);
2024-11-26 13:54:27 +00:00
$log->setServer(System::getEnv('_APP_LOGGING_SERVICE_IDENTIFIER', \gethostname()));
2024-11-13 01:29:43 +00:00
$log->setVersion($version);
$log->setType(Log::TYPE_ERROR);
$log->setMessage($error->getMessage());
$log->addTag('code', $error->getCode());
$log->addTag('verboseType', get_class($error));
$log->addTag('projectId', $project->getId() ?? '');
$log->addExtra('file', $error->getFile());
$log->addExtra('line', $error->getLine());
$log->addExtra('trace', $error->getTraceAsString());
2024-11-13 04:42:49 +00:00
2025-12-16 08:27:28 +00:00
if ($error->getPrevious() !== null) {
if ($error->getPrevious()->getMessage() != $error->getMessage()) {
$log->addExtra('previousMessage', $error->getPrevious()->getMessage());
}
$log->addExtra('previousFile', $error->getPrevious()->getFile());
$log->addExtra('previousLine', $error->getPrevious()->getLine());
}
2024-11-13 01:29:43 +00:00
2025-04-16 09:50:42 +00:00
foreach (($extras ?? []) as $key => $value) {
2024-11-13 01:29:43 +00:00
$log->addExtra($key, $value);
}
$log->setAction($action);
$isProduction = System::getEnv('_APP_ENV', 'development') === 'production';
$log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING);
try {
$responseCode = $logger->addLog($log);
Console::info('Error log pushed with status code: ' . $responseCode);
} catch (Throwable $th) {
Console::error('Error pushing log: ' . $th->getMessage());
}
}
Console::warning("Failed: {$error->getMessage()}");
Console::warning($error->getTraceAsString());
2025-12-16 08:27:28 +00:00
if ($error->getPrevious() !== null) {
if ($error->getPrevious()->getMessage() != $error->getMessage()) {
Console::warning("Previous Failed: {$error->getPrevious()->getMessage()}");
}
Console::warning("Previous File: {$error->getPrevious()->getFile()} Line: {$error->getPrevious()->getLine()}");
}
2024-11-13 01:29:43 +00:00
};
}, ['register', 'project']);
2024-10-08 07:54:40 +00:00
2025-06-12 13:18:35 +00:00
Server::setResource('executor', fn () => new Executor());
2025-12-24 01:30:02 +00:00
Server::setResource('getAudit', function (Database $dbForPlatform, callable $getProjectDB) {
return function (Document $project) use ($dbForPlatform, $getProjectDB) {
if ($project->isEmpty() || $project->getId() === 'console') {
$adapter = new AdapterDatabase($dbForPlatform);
return new UtopiaAudit($adapter);
}
$dbForProject = $getProjectDB($project);
$adapter = new AdapterDatabase($dbForProject);
return new UtopiaAudit($adapter);
};
}, ['dbForPlatform', 'getProjectDB']);
2026-01-16 09:36:35 +00:00
Server::setResource('executionsRetentionCount', function (Document $project, array $plan) {
if ($project->getId() === 'console' || empty($plan)) {
return 0;
}
return (int) ($plan['executionsRetentionCount'] ?? 100);
}, ['project', 'plan']);
2024-10-08 07:54:40 +00:00
$pools = $register->get('pools');
2023-05-29 13:58:45 +00:00
$platform = new Appwrite();
2024-05-22 13:37:45 +00:00
$args = $platform->getEnv('argv');
2023-10-12 04:55:30 +00:00
if (!isset($args[1])) {
2023-06-02 03:54:34 +00:00
Console::error('Missing worker name');
2023-10-12 04:55:30 +00:00
Console::exit(1);
}
\array_shift($args);
$workerName = $args[0];
2023-05-29 13:58:45 +00:00
if (\str_starts_with($workerName, 'databases')) {
2024-04-01 11:02:47 +00:00
$queueName = System::getEnv('_APP_QUEUE_NAME', 'database_db_main');
} else {
2024-04-01 11:02:47 +00:00
$queueName = System::getEnv('_APP_QUEUE_NAME', 'v1-' . strtolower($workerName));
}
2023-06-02 03:54:34 +00:00
try {
2023-10-12 06:11:08 +00:00
/**
* Any worker can be configured with the following env vars:
* - _APP_WORKERS_NUM The total number of worker processes
* - _APP_WORKER_PER_CORE The number of worker processes per core (ignored if _APP_WORKERS_NUM is set)
2023-11-27 11:27:16 +00:00
* - _APP_QUEUE_NAME The name of the queue to read for database events
2023-10-12 06:11:08 +00:00
*/
$platform->init(Service::TYPE_WORKER, [
'workersNum' => System::getEnv('_APP_WORKERS_NUM', 1),
'connection' => $pools->get('consumer')->pop()->getResource(),
'workerName' => strtolower($workerName) ?? null,
'queueName' => $queueName
]);
} catch (\Throwable $e) {
2024-10-08 07:54:40 +00:00
Console::error($e->getMessage() . ', File: ' . $e->getFile() . ', Line: ' . $e->getLine());
2023-06-02 03:54:34 +00:00
}
2023-05-29 13:58:45 +00:00
2024-10-08 07:54:40 +00:00
$worker = $platform->getWorker();
2023-05-29 13:58:45 +00:00
2024-10-08 07:54:40 +00:00
$worker
->error()
2023-05-29 13:58:45 +00:00
->inject('error')
->inject('logger')
2023-05-24 18:14:58 +00:00
->inject('log')
2024-10-08 07:54:40 +00:00
->inject('pools')
2024-02-15 15:12:37 +00:00
->inject('project')
->inject('authorization')
->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project, Authorization $authorization) use ($worker, $queueName) {
2024-04-01 11:02:47 +00:00
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
2023-05-29 13:58:45 +00:00
2024-01-02 13:02:11 +00:00
if ($logger) {
2023-05-29 13:58:45 +00:00
$log->setNamespace("appwrite-worker");
2024-11-26 13:54:27 +00:00
$log->setServer(System::getEnv('_APP_LOGGING_SERVICE_IDENTIFIER', \gethostname()));
2023-05-29 13:58:45 +00:00
$log->setVersion($version);
$log->setType(Log::TYPE_ERROR);
$log->setMessage($error->getMessage());
$log->setAction('appwrite-queue-' . $queueName);
2023-05-29 13:58:45 +00:00
$log->addTag('verboseType', get_class($error));
$log->addTag('code', $error->getCode());
2024-02-15 15:15:10 +00:00
$log->addTag('projectId', $project->getId() ?? 'n/a');
2023-05-29 13:58:45 +00:00
$log->addExtra('file', $error->getFile());
$log->addExtra('line', $error->getLine());
$log->addExtra('trace', $error->getTraceAsString());
$log->addExtra('roles', $authorization->getRoles());
2023-05-29 13:58:45 +00:00
2024-04-01 11:02:47 +00:00
$isProduction = System::getEnv('_APP_ENV', 'development') === 'production';
2023-05-29 13:58:45 +00:00
$log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING);
try {
$responseCode = $logger->addLog($log);
Console::info('Error log pushed with status code: ' . $responseCode);
} catch (Throwable $th) {
Console::error('Error pushing log: ' . $th->getMessage());
}
2023-05-29 13:58:45 +00:00
}
Console::error('[Error] Type: ' . get_class($error));
Console::error('[Error] Message: ' . $error->getMessage());
Console::error('[Error] File: ' . $error->getFile());
Console::error('[Error] Line: ' . $error->getLine());
});
2024-10-08 07:54:40 +00:00
$worker->start();