From bed88baa6c9d565a873bf65feaab9b1bf578932d Mon Sep 17 00:00:00 2001 From: shimon Date: Sat, 22 Jul 2023 17:08:28 +0300 Subject: [PATCH] added bucketId to cache::deleteByResource --- app/controllers/api/storage.php | 9 +--- app/controllers/shared/api.php | 5 +-- app/init.php | 2 +- app/workers/deletes.php | 76 ++++++++++++++++++++++++++++----- src/Appwrite/Event/Delete.php | 14 ++++++ 5 files changed, 84 insertions(+), 22 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 82cba1ab48..4225b862b5 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -359,8 +359,7 @@ App::post('/v1/storage/buckets/:bucketId/files') ->inject('mode') ->inject('deviceFiles') ->inject('deviceLocal') - ->inject('deletes') - ->action(function (string $bucketId, string $fileId, mixed $file, ?array $permissions, Request $request, Response $response, Database $dbForProject, Document $user, Event $events, string $mode, Device $deviceFiles, Device $deviceLocal, Delete $deletes) { + ->action(function (string $bucketId, string $fileId, mixed $file, ?array $permissions, Request $request, Response $response, Database $dbForProject, Document $user, Event $events, string $mode, Device $deviceFiles, Device $deviceLocal) { $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); @@ -654,11 +653,6 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setContext('bucket', $bucket) ; - $deletes - ->setType(DELETE_TYPE_CACHE_BY_RESOURCE) - ->setResource('file/' . $file->getId()) - ; - $metadata = null; // was causing leaks as it was passed by reference $response @@ -1416,6 +1410,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId') if ($deviceDeleted) { $deletes ->setType(DELETE_TYPE_CACHE_BY_RESOURCE) + ->setResourceType('bucket/' . $bucket->getId()) ->setResource('file/' . $fileId) ; diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index e85fdeda95..aaae656457 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -199,7 +199,7 @@ App::init() $useCache = $route->getLabel('cache', false); if ($useCache) { - $key = md5($request->getURI() . implode('*', $request->getParams())) . '*' . APP_CACHE_BUSTER; + $key = md5($request->getURI() . '*' . implode('*', $request->getParams())) . '*' . APP_CACHE_BUSTER; $cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key)); $cache = new Cache( new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId()) @@ -484,8 +484,7 @@ App::shutdown() $resourceType = $parseLabel($pattern, $responsePayload, $requestParams, $user); } - $key = md5($request->getURI() . implode('*', $request->getParams())) . '*' . APP_CACHE_BUSTER; - + $key = md5($request->getURI() . '*' . implode('*', $request->getParams())) . '*' . APP_CACHE_BUSTER; $signature = md5($data['payload']); $cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key)); $accessedAt = $cacheLog->getAttribute('accessedAt', ''); diff --git a/app/init.php b/app/init.php index d959cf24b5..9d3ceb5fcb 100644 --- a/app/init.php +++ b/app/init.php @@ -100,7 +100,7 @@ const APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT = 60; // Default maximum write rate pe const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return in list API calls const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours -const APP_CACHE_BUSTER = 504; +const APP_CACHE_BUSTER = 505; const APP_VERSION_STABLE = '1.3.5'; const APP_DATABASE_ATTRIBUTE_EMAIL = 'email'; const APP_DATABASE_ATTRIBUTE_ENUM = 'enum'; diff --git a/app/workers/deletes.php b/app/workers/deletes.php index f27bc4feb9..72c56ba73a 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -114,10 +114,10 @@ class DeletesV1 extends Worker break; case DELETE_TYPE_CACHE_BY_RESOURCE: - $this->deleteCacheByResource($project->getId()); + $this->deleteCacheByResource($project, $this->args['resource'], $this->args['resourceType']); break; case DELETE_TYPE_CACHE_BY_TIMESTAMP: - $this->deleteCacheByDate(); + $this->deleteCacheByDate($this->args['datetime']); break; default: Console::error('No delete operation for type: ' . $type); @@ -130,22 +130,76 @@ class DeletesV1 extends Worker } /** - * @param string $projectId + * @param Document $project + * @param string $resource + * @param string|null $resourceType + * @throws Exception */ - protected function deleteCacheByResource(string $projectId): void + protected function deleteCacheByResource(Document $project, string $resource, string $resourceType = null): void { - $this->deleteCacheFiles([ - Query::equal('resource', [$this->args['resource']]), - ]); + $projectId = $project->getId(); + $dbForProject = $this->getProjectDB($projectId); + + $cache = new Cache( + new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId) + ); + + $query[] = Query::equal('resource', [$resource]); + if (!empty($resourceType)) { + $query[] = Query::equal('resourceType', [$resourceType]); + } + + $this->deleteByGroup( + 'cache', + $query, + $dbForProject, + function (Document $document) use ($cache, $projectId) { + $path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId(); + + if ($cache->purge($document->getId())) { + Console::success('Deleting cache file: ' . $path); + } else { + Console::error('Failed to delete cache file: ' . $path); + } + } + ); } - protected function deleteCacheByDate(): void + /** + * @param string $datetime + * @throws Exception + */ + protected function deleteCacheByDate(string $datetime): void { - $this->deleteCacheFiles([ - Query::lessThan('accessedAt', $this->args['datetime']), - ]); + $this->deleteForProjectIds(function (string $projectId) use ($datetime) { + + $dbForProject = $this->getProjectDB($projectId); + $cache = new Cache( + new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId) + ); + + $query = [ + Query::lessThan('accessedAt', $datetime), + ]; + + $this->deleteByGroup( + 'cache', + $query, + $dbForProject, + function (Document $document) use ($cache, $projectId) { + $path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId(); + + if ($cache->purge($document->getId())) { + Console::success('Deleting cache file: ' . $path); + } else { + Console::error('Failed to delete cache file: ' . $path); + } + } + ); + }); } + protected function deleteCacheFiles($query): void { $this->deleteForProjectIds(function (string $projectId) use ($query) { diff --git a/src/Appwrite/Event/Delete.php b/src/Appwrite/Event/Delete.php index d1519121a6..448c27f622 100644 --- a/src/Appwrite/Event/Delete.php +++ b/src/Appwrite/Event/Delete.php @@ -9,6 +9,7 @@ class Delete extends Event { protected string $type = ''; protected ?Document $document = null; + protected ?string $resourceType = null; protected ?string $resource = null; protected ?string $datetime = null; protected ?string $hourlyUsageRetentionDatetime = null; @@ -102,6 +103,19 @@ class Delete extends Event return $this; } + /** + * Sets the resource type for the delete event. + * + * @param string $resourceType + * @return self + */ + public function setResourceType(string $resourceType): self + { + $this->resourceType = $resourceType; + + return $this; + } + /** * Returns the set document for the delete event. *