Compare commits

...
Author SHA1 Message Date
fogelito c6a8e5710e Merge branch '1.9.x' of https://github.com/appwrite/appwrite into update-migration-processing 2026-05-26 09:57:42 +03:00
fogelito 8685266e97 Merge branch '1.9.x' of https://github.com/appwrite/appwrite into update-migration-processing 2026-05-25 19:11:35 +03:00
fogelito b07046eaba Merge branch '1.9.x' of https://github.com/appwrite/appwrite into update-migration-processing 2026-05-24 10:19:42 +03:00
fogelito 19ab27bf57 Merge branch '1.9.x' of https://github.com/appwrite/appwrite into update-migration-processing 2026-05-20 17:39:45 +03:00
fogelito 9ad625da36 formatting 2026-05-20 16:38:17 +03:00
fogelito 26e8792b63 Use $updatedAt 2026-05-20 16:37:50 +03:00
fogelito c2df9409d6 Use $updatedAt 2026-05-20 16:00:35 +03:00
fogelito a83c01db65 Created at 2026-05-20 13:46:29 +03:00
fogelito d50dcad24a Update message 2026-05-20 13:15:54 +03:00
fogelito 151ef8ab7c console info 2026-05-20 12:41:38 +03:00
fogelito 227e47f121 return presents 2026-05-20 12:27:42 +03:00
fogelito 940fa701da return on transactions 2026-05-20 12:02:34 +03:00
fogelito 2ef2d4d498 return for stats 2026-05-20 11:53:07 +03:00
fogelito c1aeaf9bb9 Merge remote-tracking branch 'origin/update-migration-processing' into update-migration-processing 2026-05-19 16:29:57 +03:00
fogelito 2b8d035545 use constant for processing stuck 2026-05-19 16:29:45 +03:00
Shmuel FogelGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
d9e4318ab9 Update src/Appwrite/Platform/Workers/Deletes.php
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-05-19 16:01:27 +03:00
Shmuel FogelGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
4523ad5e1f Update src/Appwrite/Platform/Workers/Deletes.php
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-05-19 16:00:55 +03:00
fogelito a67930a18a Remove use 2026-05-19 15:56:19 +03:00
fogelito 24900ee08e retention 2026-05-19 15:54:56 +03:00
fogelito 586eb3ca19 updateProcessingMigrations 2026-05-19 15:49:55 +03:00
+98 -17
View File
@@ -40,6 +40,7 @@ use function Swoole\Coroutine\batch;
class Deletes extends Action
{
protected array $selects = ['$sequence', '$id', '$collection', '$permissions', '$updatedAt'];
public const PROCESSING_STUCK_RETENTION_SECONDS = 3 * 24 * 60 * 60; // 3 days
public static function getName(): string
{
@@ -223,6 +224,7 @@ class Deletes extends Action
$this->deleteExpiredTransactions($project, $getProjectDB);
$this->deleteExpiredPresences($project, $getProjectDB, $publisherForUsage);
$this->deleteOldDeployments($publisherForDeletes, $project, $getProjectDB);
$this->updateProcessingMigrations($project, $getProjectDB);
break;
case DELETE_TYPE_REPORT:
$this->deleteReport($dbForPlatform, $project, $document);
@@ -390,16 +392,59 @@ class Deletes extends Action
*/
private function deleteExpiredTargets(Document $project, callable $getProjectDB): void
{
Console::info('Delete expired targets');
Targets::delete($getProjectDB($project), Query::equal('expired', [true]));
}
private function deleteSessionTargets(Document $project, callable $getProjectDB, Document $session): void
{
Console::info('Delete session targets');
Targets::delete($getProjectDB($project), Query::equal('sessionInternalId', [$session->getSequence()]));
}
private function updateProcessingMigrations(Document $project, callable $getProjectDB): void
{
if ($project->getId() === 'console') {
return;
}
Console::info('Update processing migrations');
/** @var Database $dbForProject */
$dbForProject = $getProjectDB($project);
$date = DateTime::addSeconds(new \DateTime(), -self::PROCESSING_STUCK_RETENTION_SECONDS);
$queries = [
Query::select($this->selects),
Query::equal('status', ['processing']),
Query::lessThan('$updatedAt', $date),
];
$this->listByGroup(
'migrations',
$queries,
$dbForProject,
function (Document $migration) use ($dbForProject, $project) {
try {
$dbForProject->updateDocument('migrations', $migration->getId(), new Document([
'status' => 'failed'
]));
} catch (Throwable $th) {
Console::error("Failed to update processing migration {$migration->getId()} for project {$project->getId()}: " . $th->getMessage());
}
}
);
}
private function deleteOldDeployments(DeletePublisher $publisherForDeletes, Document $project, callable $getProjectDB): void
{
if ($project->getId() === 'console') {
return;
}
Console::info('Delete old deployments');
/** @var Database $dbForProject */
$dbForProject = $getProjectDB($project);
@@ -545,6 +590,12 @@ class Deletes extends Action
*/
private function deleteUsageStats(Document $project, callable $getProjectDB, callable $getLogsDB, string $hourlyUsageRetentionDatetime): void
{
if ($project->getId() === 'console') {
return;
}
Console::info('Delete usage stats');
/** @var Database $dbForProject */
$dbForProject = $getProjectDB($project);
@@ -559,19 +610,17 @@ class Deletes extends Action
Query::orderDesc(),
], $dbForProject);
if ($project->getId() !== 'console') {
/** @var Database $dbForLogs */
$dbForLogs = call_user_func($getLogsDB, $project);
/** @var Database $dbForLogs */
$dbForLogs = call_user_func($getLogsDB, $project);
// Delete Usage stats from logsDB
$this->deleteByGroup('stats', [
Query::select($selects),
Query::equal('period', ['1h']),
Query::lessThan('time', $hourlyUsageRetentionDatetime),
Query::orderDesc('time'),
Query::orderDesc(),
], $dbForLogs);
}
// Delete Usage stats from logsDB
$this->deleteByGroup('stats', [
Query::select($selects),
Query::equal('period', ['1h']),
Query::lessThan('time', $hourlyUsageRetentionDatetime),
Query::orderDesc('time'),
Query::orderDesc(),
], $dbForLogs);
}
/**
@@ -981,6 +1030,12 @@ class Deletes extends Action
*/
private function deleteExecutionLogs(Document $project, callable $getProjectDB, string $datetime, ?int $executionsRetentionCount = 0): void
{
if ($project->getId() === 'console') {
return;
}
Console::info('Delete execution logs');
/** @var Database $dbForProject */
$dbForProject = $getProjectDB($project);
@@ -1012,7 +1067,7 @@ class Deletes extends Action
?string $resourceInternalId = null,
?string $resourceType = null
): void {
if ($executionsRetentionCount <= 0) {
if ($executionsRetentionCount <= 0 || $project->getId() === 'console') {
return;
}
@@ -1077,6 +1132,8 @@ class Deletes extends Action
*/
private function deleteExpiredSessions(Document $project, callable $getProjectDB): void
{
Console::info('Delete expired sessions');
$dbForProject = $getProjectDB($project);
$duration = $project->getAttribute('auths', [])['duration'] ?? TOKEN_EXPIRATION_LOGIN_LONG;
$expired = DateTime::addSeconds(new \DateTime(), -1 * $duration);
@@ -1150,6 +1207,8 @@ class Deletes extends Action
*/
private function deleteAuditLogs(Document $project, callable $getAudit, string $auditRetention): void
{
Console::info('Delete audit logs');
$projectId = $project->getId();
/** @var Audit $audit */
$audit = $getAudit($project);
@@ -1520,6 +1579,11 @@ class Deletes extends Action
): void {
$start = \microtime(true);
$message = 'collection:'.$database->getNamespace().'_'.$collection;
if ($database->getSharedTables()) {
$message .= ' Tenant:'.$database->getTenant();
}
/**
* deleteDocuments uses a cursor, we need to add a unique order by field or use default
*/
@@ -1530,13 +1594,13 @@ class Deletes extends Action
onNext: $callback
);
} catch (Throwable $th) {
$tenant = $database->getSharedTables() ? 'Tenant:' . $database->getTenant() : '';
Console::error("Failed to delete documents for collection:{$database->getNamespace()}_{$collection} {$tenant} :{$th->getMessage()}");
$tenant = $database->getSharedTables() ? 'Tenant:'. $database->getTenant() : '';
Console::error("Failed to delete documents for {$message} :{$th->getMessage()}");
return;
}
$end = \microtime(true);
Console::info("Deleted {$count} documents by group in " . ($end - $start) . " seconds");
Console::info("Deleted {$count} documents by group in " . ($end - $start) . " seconds {$message}");
}
/**
@@ -1583,7 +1647,12 @@ class Deletes extends Action
$end = \microtime(true);
Console::info("Listed {$count} documents by group in " . ($end - $start) . " seconds");
$message = 'collection:'.$database->getNamespace().'_'.$collection;
if ($database->getSharedTables()) {
$message .= ' Tenant:'.$database->getTenant();
}
Console::info("Listed {$count} documents by group in " . ($end - $start) . " seconds {$message}");
}
/**
@@ -1723,6 +1792,12 @@ class Deletes extends Action
private function deleteExpiredTransactions(Document $project, callable $getProjectDB): void
{
if ($project->getId() === 'console') {
return;
}
Console::info('Delete expired transactions');
$dbForProject = $getProjectDB($project);
$transactionInternalIds = [];
@@ -1751,6 +1826,12 @@ class Deletes extends Action
private function deleteExpiredPresences(Document $project, callable $getProjectDB, UsagePublisher $publisherForUsage): void
{
if ($project->getId() === 'console') {
return;
}
Console::info('Delete expired presences');
$dbForProject = $getProjectDB($project);
$now = DateTime::format(new \DateTime());