mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-03 14:19:01 +02:00
0ef959d05b
* Rename files to mjs * Rename test files to mjs * Update CODEOWNERS * Update files to ESM * Update test files to ESM * Update RestoreManager.test.mjs * Remove unused `AdminAuthorizationHelper` mock and stub * Remove unnecessary return GitOrigin-RevId: 2b9ef126de1d8964afbc6e5641cca36712655866
140 lines
3.8 KiB
JavaScript
140 lines
3.8 KiB
JavaScript
import OError from '@overleaf/o-error'
|
|
import logger from '@overleaf/logger'
|
|
import DocstoreManager from '../Docstore/DocstoreManager.js'
|
|
import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.js'
|
|
import ProjectGetter from '../Project/ProjectGetter.js'
|
|
import ProjectUpdateHandler from '../Project/ProjectUpdateHandler.js'
|
|
import { Project } from '../../models/Project.js'
|
|
import Modules from '../../infrastructure/Modules.js'
|
|
import { READ_PREFERENCE_SECONDARY } from '../../infrastructure/mongodb.js'
|
|
import { callbackifyAll } from '@overleaf/promise-utils'
|
|
import Metrics from '@overleaf/metrics'
|
|
|
|
const MILISECONDS_IN_DAY = 86400000
|
|
|
|
function findInactiveProjects(limit, daysOld) {
|
|
const oldProjectDate = new Date() - MILISECONDS_IN_DAY * daysOld
|
|
try {
|
|
// use $not $gt to catch non-opened projects where lastOpened is null
|
|
// return a cursor instead of executing the query
|
|
return Project.find({
|
|
lastOpened: { $not: { $gt: oldProjectDate } },
|
|
})
|
|
.where('active')
|
|
.equals(true)
|
|
.select(['_id', 'lastOpened'])
|
|
.limit(limit)
|
|
.read(READ_PREFERENCE_SECONDARY)
|
|
.cursor()
|
|
} catch (err) {
|
|
logger.err({ err }, 'could not get projects for deactivating')
|
|
throw err // Re-throw the error to be handled by the caller
|
|
}
|
|
}
|
|
|
|
const InactiveProjectManager = {
|
|
async reactivateProjectIfRequired(projectId) {
|
|
let project
|
|
try {
|
|
project = await ProjectGetter.promises.getProject(projectId, {
|
|
active: true,
|
|
})
|
|
} catch (err) {
|
|
OError.tag(err, 'error getting project', {
|
|
project_id: projectId,
|
|
})
|
|
throw err
|
|
}
|
|
|
|
logger.debug(
|
|
{ projectId, active: project.active },
|
|
'seeing if need to reactivate project'
|
|
)
|
|
|
|
if (project.active) {
|
|
return
|
|
}
|
|
|
|
try {
|
|
await DocstoreManager.promises.unarchiveProject(projectId)
|
|
} catch (err) {
|
|
OError.tag(err, 'error reactivating project in docstore', {
|
|
project_id: projectId,
|
|
})
|
|
throw err
|
|
}
|
|
|
|
await ProjectUpdateHandler.promises.markAsActive(projectId)
|
|
},
|
|
|
|
async deactivateOldProjects(limit, daysOld) {
|
|
if (limit == null) {
|
|
limit = 10
|
|
}
|
|
if (daysOld == null) {
|
|
daysOld = 360
|
|
}
|
|
|
|
logger.debug('deactivating projects')
|
|
|
|
const processedProjects = []
|
|
|
|
for await (const project of findInactiveProjects(limit, daysOld)) {
|
|
processedProjects.push(project)
|
|
try {
|
|
await InactiveProjectManager.deactivateProject(project._id)
|
|
} catch (err) {
|
|
logger.err(
|
|
{ projectId: project._id, err },
|
|
'unable to deactivate project'
|
|
)
|
|
}
|
|
}
|
|
|
|
logger.debug(
|
|
{ numberOfProjects: processedProjects.length },
|
|
'finished deactivating projects'
|
|
)
|
|
|
|
return processedProjects
|
|
},
|
|
|
|
async deactivateProject(projectId) {
|
|
logger.debug({ projectId }, 'deactivating inactive project')
|
|
|
|
// ensure project is removed from document updater (also flushes updates to history)
|
|
try {
|
|
await DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete(
|
|
projectId
|
|
)
|
|
} catch (err) {
|
|
logger.warn(
|
|
{ err, projectId },
|
|
'error flushing project to mongo when archiving'
|
|
)
|
|
Metrics.inc('inactive-project', 1, {
|
|
method: 'archive',
|
|
status: 'flush-error',
|
|
})
|
|
throw err
|
|
}
|
|
|
|
await Modules.promises.hooks.fire('deactivateProject', projectId)
|
|
|
|
// now archive the project and mark it as inactive
|
|
try {
|
|
await DocstoreManager.promises.archiveProject(projectId)
|
|
await ProjectUpdateHandler.promises.markAsInactive(projectId)
|
|
} catch (err) {
|
|
logger.warn({ err, projectId }, 'error deactivating project')
|
|
throw err
|
|
}
|
|
},
|
|
}
|
|
|
|
export default {
|
|
...callbackifyAll(InactiveProjectManager),
|
|
promises: InactiveProjectManager,
|
|
findInactiveProjects,
|
|
}
|