overleaf/services/track-changes/pack.coffee

109 lines
3.1 KiB
CoffeeScript

Settings = require "settings-sharelatex"
fs = require("fs")
{db, ObjectId} = require "./app/coffee/mongojs"
async = require("async")
BSON=db.bson.BSON
util = require 'util'
_ = require 'underscore'
PackManager = require "./app/coffee/PackManager.coffee"
lineReader = require "line-reader"
cli = require "cli"
options = cli.parse {
'dry-run': ['n', 'do not write to database'],
'fast': [false, 'no delays on writes']
}
DB_WRITE_DELAY = if options.fast then 0 else 2000
DOCUMENT_PACK_DELAY = if options.fast then 0 else 1000
packDocHistory = (doc_id, callback) ->
util.log "starting pack operation for #{doc_id}"
getDocHistory doc_id, (err, docs) ->
return callback(err) if err?
origDocs = docs.length
PackManager.convertDocsToPacks docs, (err, packs) ->
return callback(err) if err?
util.log "docs #{origDocs} packs #{packs.length}"
if packs.length
if options['dry-run']
util.log 'dry-run, skipping write packs'
return callback()
savePacks packs, (err) ->
return callback(err) if err?
# check the history again
getDocHistory doc_id, callback
else
util.log "no packs to write"
callback null, null
# retrieve document ops/packs and check them
getDocHistory = (doc_id, callback) ->
db.docHistory.find({doc_id:ObjectId(doc_id)}).sort {v:1}, (err, docs) ->
return callback(err) if err?
# for safety, do a consistency check of the history
util.log "checking history for #{doc_id}"
PackManager.checkHistory docs, (err) ->
return callback(err) if err?
callback(err, docs)
#PackManager.deleteExpiredPackOps docs, (err) ->
# return callback(err) if err?
# callback err, docs
safeInsert = (packObj, callback) ->
if shutdownRequested
return callback('shutdown')
PackManager.insertPack packObj, (err, result) ->
setTimeout () ->
callback(err,result)
, DB_WRITE_DELAY
savePacks = (packs, callback) ->
async.eachSeries packs, safeInsert, (err, result) ->
if err?
util.log "error writing packs"
callback err, result
else
util.log "done writing packs"
callback()
readFile = (file, callback) ->
ids = []
lineReader.eachLine file, (line) ->
result = line.match(/[0-9a-f]{24}/)
if result?
ids.push result[0]
.then () ->
callback(null, ids)
todoFile = cli.args[1]
doneFile = cli.args[2]
util.log "reading from #{todoFile}"
util.log "logging progress to #{doneFile}"
fs.appendFileSync doneFile, '# starting pack run at ' + new Date() + '\n'
shutdownRequested = false
process.on 'SIGINT', () ->
util.log "Gracefully shutting down from SIGINT"
shutdownRequested = true
readFile todoFile, (err, todo) ->
readFile doneFile, (err, done) ->
pending = _.difference todo, done
async.eachSeries pending, (doc_id, callback) ->
packDocHistory doc_id, (err, result) ->
if err?
console.log "ERROR:", err, result
return callback(err)
else if not options['dry-run']
fs.appendFileSync doneFile, doc_id + '\n'
if shutdownRequested
return callback('shutdown')
setTimeout () ->
callback(err, result)
, DOCUMENT_PACK_DELAY
, (err, results) ->
if err?
console.log 'error:', err
util.log 'closing db'
db.close()