diff --git a/services/history-v1/storage/lib/backup_store/index.js b/services/history-v1/storage/lib/backup_store/index.js index da7944786a..06bd16c139 100644 --- a/services/history-v1/storage/lib/backup_store/index.js +++ b/services/history-v1/storage/lib/backup_store/index.js @@ -1,5 +1,5 @@ const { Binary, ObjectId } = require('mongodb') -const { projects, backedUpBlobs } = require('../mongodb') +const { projects, deletedProjects, backedUpBlobs } = require('../mongodb') const OError = require('@overleaf/o-error') // List projects with pending backups older than the specified interval @@ -79,6 +79,13 @@ async function getBackupStatus(projectId) { } ) if (!project) { + // Check whether the project was deleted + const deletedProject = await deletedProjects.findOne({ + 'deleterData.deletedProjectId': new ObjectId(projectId), + }) + if (deletedProject) { + throw new Error('Project deleted') + } throw new Error('Project not found') } return { diff --git a/services/history-v1/storage/lib/mongodb.js b/services/history-v1/storage/lib/mongodb.js index 210dd87354..98ed9555cb 100644 --- a/services/history-v1/storage/lib/mongodb.js +++ b/services/history-v1/storage/lib/mongodb.js @@ -14,6 +14,7 @@ const blobs = db.collection('projectHistoryBlobs') const globalBlobs = db.collection('projectHistoryGlobalBlobs') const shardedBlobs = db.collection('projectHistoryShardedBlobs') const projects = db.collection('projects') +const deletedProjects = db.collection('deletedProjects') // Temporary collection for tracking progress of backed up old blobs (without a hash). // The initial sync process will be able to skip over these. // Schema: _id: projectId, blobs: [Binary] @@ -32,6 +33,7 @@ module.exports = { blobs, globalBlobs, projects, + deletedProjects, shardedBlobs, backedUpBlobs, cleanupTestDatabase, diff --git a/services/history-v1/storage/scripts/backup_worker.mjs b/services/history-v1/storage/scripts/backup_worker.mjs index 1097bb04b9..ce0f433dd5 100644 --- a/services/history-v1/storage/scripts/backup_worker.mjs +++ b/services/history-v1/storage/scripts/backup_worker.mjs @@ -114,9 +114,14 @@ async function runBackup(projectId, data, job) { } return `backup completed ${projectId}` } catch (err) { - metrics.inc('backup_worker_project', 1, { status: 'failed' }) - logger.error({ projectId, err }, 'backup failed') - throw err // Re-throw to mark job as failed + if (err.message === 'Project deleted') { + metrics.inc('backup_worker_project', 1, { status: 'deleted' }) + logger.warn({ projectId, err }, 'skipping backup of deleted project') + } else { + metrics.inc('backup_worker_project', 1, { status: 'failed' }) + logger.error({ projectId, err }, 'backup failed') + throw err // Re-throw to mark job as failed + } } }