2021-11-24 04:22:21 -05:00
|
|
|
const Settings = require('@overleaf/settings')
|
|
|
|
const logger = require('@overleaf/logger')
|
|
|
|
const rclient = require('@overleaf/redis-wrapper').createClient(
|
|
|
|
Settings.redis.documentupdater
|
|
|
|
)
|
|
|
|
const keys = Settings.redis.documentupdater.key_schema
|
|
|
|
const ProjectFlusher = require('app/js/ProjectFlusher')
|
|
|
|
const DocumentManager = require('app/js/DocumentManager')
|
2024-11-08 05:21:56 -05:00
|
|
|
const util = require('node:util')
|
2021-11-24 04:22:21 -05:00
|
|
|
const flushAndDeleteDocWithLock = util.promisify(
|
|
|
|
DocumentManager.flushAndDeleteDocWithLock
|
|
|
|
)
|
|
|
|
|
|
|
|
async function flushAndDeleteDocs(dockeys, options) {
|
|
|
|
const docIds = ProjectFlusher._extractIds(dockeys)
|
|
|
|
for (const docId of docIds) {
|
|
|
|
const pathname = await rclient.get(keys.pathname({ doc_id: docId }))
|
|
|
|
if (!pathname) {
|
|
|
|
const projectId = await rclient.get(keys.projectKey({ doc_id: docId }))
|
|
|
|
if (!projectId) {
|
|
|
|
// await deleteDanglingDoc(projectId, docId, pathname, options)
|
|
|
|
logger.info(
|
|
|
|
{ projectId, docId, pathname },
|
|
|
|
'skipping doc with empty pathname and project id'
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
await flushAndDeleteDoc(projectId, docId, pathname, options)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function flushAndDeleteDoc(projectId, docId, pathname, options) {
|
|
|
|
if (options.dryRun) {
|
|
|
|
logger.info(
|
|
|
|
{ projectId, docId, pathname },
|
|
|
|
'dry run mode - would flush doc with empty pathname'
|
|
|
|
)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
logger.info(
|
|
|
|
{ projectId, docId, pathname },
|
|
|
|
'flushing doc with empty pathname'
|
|
|
|
)
|
|
|
|
try {
|
|
|
|
await flushAndDeleteDocWithLock(projectId, docId, {})
|
|
|
|
} catch (err) {
|
|
|
|
logger.error(
|
|
|
|
{ projectId, docId, pathname, err },
|
|
|
|
'error flushing and deleting doc without pathname'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function cleanUpDocs(options) {
|
|
|
|
logger.info({ options }, 'cleaning up docs without pathnames')
|
|
|
|
let cursor = 0
|
|
|
|
do {
|
|
|
|
const [newCursor, doclinesKeys] = await rclient.scan(
|
|
|
|
cursor,
|
|
|
|
'MATCH',
|
|
|
|
keys.docLines({ doc_id: '*' }),
|
|
|
|
'COUNT',
|
|
|
|
options.limit
|
|
|
|
)
|
|
|
|
await flushAndDeleteDocs(doclinesKeys, options)
|
|
|
|
cursor = newCursor
|
|
|
|
} while (cursor !== '0')
|
|
|
|
}
|
|
|
|
|
2021-11-25 09:08:16 -05:00
|
|
|
cleanUpDocs({ limit: 1000, dryRun: process.env.DRY_RUN !== 'false' })
|
2021-11-24 04:22:21 -05:00
|
|
|
.then(result => {
|
2021-11-25 09:08:16 -05:00
|
|
|
rclient.quit()
|
2021-11-24 04:22:21 -05:00
|
|
|
console.log('DONE')
|
|
|
|
})
|
|
|
|
.catch(function (error) {
|
2021-11-30 10:06:47 -05:00
|
|
|
console.error(error)
|
|
|
|
process.exit(1)
|
2021-11-24 04:22:21 -05:00
|
|
|
})
|