mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
optimizations
fix: update presence handling to include hostname and correct usage trigger parameter improvement: removed an external findOne call to the db and used the timestamps for knowing upsert did an update or a create
This commit is contained in:
@@ -6,7 +6,10 @@ use Appwrite\Certificates\Adapter as CertificatesAdapter;
|
||||
use Appwrite\Deletes\Identities;
|
||||
use Appwrite\Deletes\Targets;
|
||||
use Appwrite\Event\Delete as DeleteEvent;
|
||||
use Appwrite\Event\Message\Usage;
|
||||
use Appwrite\Event\Publisher\Usage as UsagePublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Usage\Context as UsageContext;
|
||||
use Executor\Executor;
|
||||
use Throwable;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Database as AbuseDatabase;
|
||||
@@ -68,6 +71,7 @@ class Deletes extends Action
|
||||
->inject('log')
|
||||
->inject('queueForDeletes')
|
||||
->inject('getAudit')
|
||||
->inject('publisherForUsage')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -95,6 +99,7 @@ class Deletes extends Action
|
||||
Log $log,
|
||||
DeleteEvent $queueForDeletes,
|
||||
callable $getAudit,
|
||||
UsagePublisher $publisherForUsage,
|
||||
): void {
|
||||
$payload = $message->getPayload();
|
||||
|
||||
@@ -214,7 +219,7 @@ class Deletes extends Action
|
||||
$this->deleteUsageStats($project, $getProjectDB, $getLogsDB, $hourlyUsageRetentionDatetime);
|
||||
$this->deleteExpiredSessions($project, $getProjectDB);
|
||||
$this->deleteExpiredTransactions($project, $getProjectDB);
|
||||
$this->deleteExpiredPresences($project, $getProjectDB);
|
||||
$this->deleteExpiredPresences($project, $getProjectDB, $publisherForUsage);
|
||||
$this->deleteOldDeployments($queueForDeletes, $project, $getProjectDB);
|
||||
break;
|
||||
default:
|
||||
@@ -1707,7 +1712,7 @@ class Deletes extends Action
|
||||
});
|
||||
}
|
||||
|
||||
private function deleteExpiredPresences(Document $project, callable $getProjectDB): void
|
||||
private function deleteExpiredPresences(Document $project, callable $getProjectDB, UsagePublisher $publisherForUsage): void
|
||||
{
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
@@ -1720,7 +1725,7 @@ class Deletes extends Action
|
||||
$now = DateTime::format(new \DateTime());
|
||||
$oldestAllowed = DateTime::format((new \DateTime())->sub(\DateInterval::createFromDateString('30 days')));
|
||||
|
||||
$dbForProject->deleteDocuments('presenceLogs', [
|
||||
$deleted = $dbForProject->deleteDocuments('presenceLogs', [
|
||||
Query::or([
|
||||
Query::and([
|
||||
Query::isNotNull('expiresAt'),
|
||||
@@ -1731,5 +1736,13 @@ class Deletes extends Action
|
||||
], onError: function (Throwable $th) {
|
||||
// Swallow errors to avoid breaking the cleanup process
|
||||
});
|
||||
|
||||
if ($deleted > 0) {
|
||||
$usage = (new UsageContext())->addMetric(METRIC_USERS_PRESENCE, -$deleted);
|
||||
$publisherForUsage->enqueue(new Usage(
|
||||
project: $project,
|
||||
metrics: $usage->getMetrics(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class Presence extends Action
|
||||
|
||||
/**
|
||||
* @param array<int, string>|null $permissions
|
||||
* @param Closure(int, string): void $triggerPresenceUsage
|
||||
* @param Closure(int, Document): void $triggerPresenceUsage
|
||||
* @param Closure(?Document, User, string, Document): void $triggerPresenceEvent
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
@@ -78,6 +78,9 @@ class Presence extends Action
|
||||
'userId' => $user->getId(),
|
||||
'source' => 'realtime',
|
||||
'status' => $status,
|
||||
// Pod identity, used by the realtime worker's startup sweep to clean up rows
|
||||
// orphaned by a previous incarnation of this hostname (i.e. pod crash before onClose ran).
|
||||
'hostname' => \gethostname() ?: null,
|
||||
];
|
||||
if ($metadata !== null) {
|
||||
$presenceData['metadata'] = $metadata;
|
||||
@@ -92,16 +95,16 @@ class Presence extends Action
|
||||
$presenceId,
|
||||
(string) $user->getSequence(),
|
||||
function () use ($project, $triggerPresenceUsage): void {
|
||||
$triggerPresenceUsage(1, $project->getId());
|
||||
$triggerPresenceUsage(1, $project);
|
||||
},
|
||||
);
|
||||
|
||||
$presence->removeAttribute('hostname');
|
||||
|
||||
$realtime->connections[$connectionId]['presences'] = \array_merge(
|
||||
$realtime->connections[$connectionId]['presences'] ?? [],
|
||||
[$presence->getId()],
|
||||
);
|
||||
// Stash the Document keyed by ID so onClose can build delete-event payloads without
|
||||
// re-reading the row from the DB. hostname is already stripped above so it won't leak
|
||||
// into the realtime payload sent to subscribers.
|
||||
$realtime->connections[$connectionId]['presences'][$presence->getId()] = $presence;
|
||||
|
||||
$triggerPresenceEvent($project, $user, 'presences.[presenceId].upsert', $presence);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user