feature(backups): cache snapshots and last backup timestamps

This commit is contained in:
Houkime 2023-04-03 18:18:23 +00:00
parent ae065867b3
commit 18d5cd2b83

View file

@ -1,4 +1,5 @@
from typing import List from typing import List, Optional
from datetime import datetime
from selfprivacy_api.models.backup.snapshot import Snapshot from selfprivacy_api.models.backup.snapshot import Snapshot
from selfprivacy_api.models.backup.provider import BackupProviderModel from selfprivacy_api.models.backup.provider import BackupProviderModel
@ -17,6 +18,10 @@ from selfprivacy_api.backup.providers import get_provider, get_kind
from selfprivacy_api.graphql.queries.providers import BackupProvider from selfprivacy_api.graphql.queries.providers import BackupProvider
# a hack to store file path. # a hack to store file path.
REDIS_SNAPSHOT_CACHE_EXPIRE_SECONDS = 24 * 60 * 60 # one day
REDIS_SNAPSHOTS_PREFIX = "backups:snapshots:"
REDIS_LAST_BACKUP_PREFIX = "backups:last-backed-up:"
REDIS_REPO_PATH_KEY = "backups:test_repo_path" REDIS_REPO_PATH_KEY = "backups:test_repo_path"
REDIS_PROVIDER_KEY = "backups:provider" REDIS_PROVIDER_KEY = "backups:provider"
@ -40,6 +45,35 @@ class Backups:
redis.set(REDIS_REPO_PATH_KEY, file_path) redis.set(REDIS_REPO_PATH_KEY, file_path)
Backups.store_provider_redis(provider) Backups.store_provider_redis(provider)
@staticmethod
def _redis_last_backup_key(service_id):
return REDIS_LAST_BACKUP_PREFIX + service_id
@staticmethod
def _redis_snapshot_key(snapshot: Snapshot):
return REDIS_SNAPSHOTS_PREFIX + snapshot.id
@staticmethod
def get_last_backed_up(service: Service) -> Optional[datetime]:
return Backups._get_last_backup_time_redis(service.get_id())
@staticmethod
def _get_last_backup_time_redis(service_id: str) -> Optional[datetime]:
key = Backups._redis_last_backup_key(service_id)
if not redis.exists(key):
return None
snapshot = hash_as_model(redis, key)
return snapshot.created_at
@staticmethod
def _store_last_snapshot(service_id: str, snapshot: Snapshot):
store_model_as_hash(redis, Backups._redis_last_backup_key(service_id), snapshot)
snapshot_key = Backups._redis_snapshot_key(snapshot)
store_model_as_hash(redis, snapshot_key, snapshot)
redis.expire(snapshot_key, REDIS_SNAPSHOT_CACHE_EXPIRE_SECONDS)
@staticmethod @staticmethod
def provider(): def provider():
return Backups.lookup_provider() return Backups.lookup_provider()
@ -82,9 +116,16 @@ class Backups:
def reset(): def reset():
redis.delete(REDIS_PROVIDER_KEY) redis.delete(REDIS_PROVIDER_KEY)
redis.delete(REDIS_REPO_PATH_KEY) redis.delete(REDIS_REPO_PATH_KEY)
for key in redis.keys(REDIS_INITTED_CACHE_PREFIX + "*"): for key in redis.keys(REDIS_INITTED_CACHE_PREFIX + "*"):
redis.delete(key) redis.delete(key)
for key in redis.keys(REDIS_SNAPSHOTS_PREFIX + "*"):
redis.delete(key)
for key in redis.keys(REDIS_LAST_BACKUP_PREFIX + "*"):
redis.delete(key)
@staticmethod @staticmethod
def lookup_provider() -> AbstractBackupProvider: def lookup_provider() -> AbstractBackupProvider:
redis_provider = Backups.load_provider_redis() redis_provider = Backups.load_provider_redis()
@ -129,7 +170,9 @@ class Backups:
repo_name = service.get_id() repo_name = service.get_id()
service.pre_backup() service.pre_backup()
Backups.provider().backuper.start_backup(folder, repo_name) snapshot = Backups.provider().backuper.start_backup(folder, repo_name)
Backups._store_last_snapshot(repo_name, snapshot)
service.post_restore() service.post_restore()
@staticmethod @staticmethod