overleaf/services/document-updater/app/coffee/DocumentManager.coffee

206 lines
8.7 KiB
CoffeeScript
Raw Normal View History

2014-02-12 05:40:42 -05:00
RedisManager = require "./RedisManager"
PersistenceManager = require "./PersistenceManager"
DiffCodec = require "./DiffCodec"
logger = require "logger-sharelatex"
Metrics = require "./Metrics"
2016-11-28 05:14:42 -05:00
HistoryManager = require "./HistoryManager"
WebRedisManager = require "./WebRedisManager"
Errors = require "./Errors"
RangesManager = require "./RangesManager"
2014-02-12 05:40:42 -05:00
module.exports = DocumentManager =
2016-09-02 09:47:41 -04:00
getDoc: (project_id, doc_id, _callback = (error, lines, version, alreadyLoaded) ->) ->
2014-02-12 05:40:42 -05:00
timer = new Metrics.Timer("docManager.getDoc")
callback = (args...) ->
timer.done()
_callback(args...)
RedisManager.getDoc project_id, doc_id, (error, lines, version, ranges) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
if !lines? or !version?
logger.log {project_id, doc_id}, "doc not in redis so getting from persistence API"
PersistenceManager.getDoc project_id, doc_id, (error, lines, version, ranges) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
logger.log {project_id, doc_id, lines, version}, "got doc from persistence API"
RedisManager.putDocInMemory project_id, doc_id, lines, version, ranges, (error) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
callback null, lines, version, ranges, false
2014-02-12 05:40:42 -05:00
else
callback null, lines, version, ranges, true
2014-02-12 05:40:42 -05:00
getDocAndRecentOps: (project_id, doc_id, fromVersion, _callback = (error, lines, version, recentOps, ranges) ->) ->
2014-02-12 05:40:42 -05:00
timer = new Metrics.Timer("docManager.getDocAndRecentOps")
callback = (args...) ->
timer.done()
_callback(args...)
DocumentManager.getDoc project_id, doc_id, (error, lines, version, ranges) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
if fromVersion == -1
callback null, lines, version, [], ranges
2014-02-12 05:40:42 -05:00
else
RedisManager.getPreviousDocOps doc_id, fromVersion, version, (error, ops) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
callback null, lines, version, ops, ranges
2014-02-12 05:40:42 -05:00
setDoc: (project_id, doc_id, newLines, source, user_id, undoing, _callback = (error) ->) ->
2014-02-12 05:40:42 -05:00
timer = new Metrics.Timer("docManager.setDoc")
callback = (args...) ->
timer.done()
_callback(args...)
if !newLines?
return callback(new Error("No lines were provided to setDoc"))
UpdateManager = require "./UpdateManager"
DocumentManager.getDoc project_id, doc_id, (error, oldLines, version, ranges, alreadyLoaded) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
if oldLines? and oldLines.length > 0 and oldLines[0].text?
logger.log doc_id: doc_id, project_id: project_id, oldLines: oldLines, newLines: newLines, "document is JSON so not updating"
return callback(null)
logger.log doc_id: doc_id, project_id: project_id, oldLines: oldLines, newLines: newLines, "setting a document via http"
DiffCodec.diffAsShareJsOp oldLines, newLines, (error, op) ->
return callback(error) if error?
if undoing
for o in op or []
o.u = true # Turn on undo flag for each op for track changes
2014-02-12 05:40:42 -05:00
update =
doc: doc_id
op: op
v: version
meta:
type: "external"
source: source
user_id: user_id
UpdateManager.applyUpdate project_id, doc_id, update, (error) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
# If the document was loaded already, then someone has it open
# in a project, and the usual flushing mechanism will happen.
# Otherwise we should remove it immediately since nothing else
# is using it.
if alreadyLoaded
DocumentManager.flushDocIfLoaded project_id, doc_id, (error) ->
return callback(error) if error?
callback null
else
DocumentManager.flushAndDeleteDoc project_id, doc_id, (error) ->
return callback(error) if error?
callback null
2014-02-12 05:40:42 -05:00
flushDocIfLoaded: (project_id, doc_id, _callback = (error) ->) ->
timer = new Metrics.Timer("docManager.flushDocIfLoaded")
callback = (args...) ->
timer.done()
_callback(args...)
RedisManager.getDoc project_id, doc_id, (error, lines, version, ranges) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
if !lines? or !version?
logger.log project_id: project_id, doc_id: doc_id, "doc is not loaded so not flushing"
2016-09-02 09:47:41 -04:00
callback null # TODO: return a flag to bail out, as we go on to remove doc from memory?
2014-02-12 05:40:42 -05:00
else
logger.log project_id: project_id, doc_id: doc_id, version: version, "flushing doc"
PersistenceManager.setDoc project_id, doc_id, lines, version, ranges, (error) ->
2014-02-12 05:40:42 -05:00
return callback(error) if error?
callback null
2014-02-12 05:40:42 -05:00
flushAndDeleteDoc: (project_id, doc_id, _callback = (error) ->) ->
timer = new Metrics.Timer("docManager.flushAndDeleteDoc")
callback = (args...) ->
timer.done()
_callback(args...)
DocumentManager.flushDocIfLoaded project_id, doc_id, (error) ->
return callback(error) if error?
# Flush in the background since it requires and http request
# to track changes
2016-11-28 05:14:42 -05:00
HistoryManager.flushDocChanges project_id, doc_id, (err) ->
if err?
logger.err {err, project_id, doc_id}, "error flushing to track changes"
2014-02-12 05:40:42 -05:00
RedisManager.removeDocFromMemory project_id, doc_id, (error) ->
return callback(error) if error?
callback null
acceptChange: (project_id, doc_id, change_id, _callback = (error) ->) ->
timer = new Metrics.Timer("docManager.acceptChange")
callback = (args...) ->
timer.done()
_callback(args...)
DocumentManager.getDoc project_id, doc_id, (error, lines, version, ranges) ->
return callback(error) if error?
if !lines? or !version?
return callback(new Errors.NotFoundError("document not found: #{doc_id}"))
RangesManager.acceptChange change_id, ranges, (error, new_ranges) ->
return callback(error) if error?
RedisManager.updateDocument doc_id, lines, version, [], new_ranges, (error) ->
return callback(error) if error?
callback()
2017-05-04 10:32:54 -04:00
bulkAcceptChanges: (project_id, doc_id, change_ids, _callback = (error) ->) ->
timer = new Metrics.Timer("docManager.bulkAcceptChanges")
callback = (args...) ->
timer.done()
_callback(args...)
DocumentManager.getDoc project_id, doc_id, (error, lines, version, ranges) ->
return callback(error) if error?
if !lines? or !version?
return callback(new Errors.NotFoundError("document not found: #{doc_id}"))
RangesManager.bulkAcceptChanges change_ids, ranges, (error, new_ranges) ->
return callback(error) if error?
RedisManager.updateDocument doc_id, lines, version, [], new_ranges, (error) ->
return callback(error) if error?
callback()
2017-01-24 09:57:11 -05:00
deleteComment: (project_id, doc_id, comment_id, _callback = (error) ->) ->
timer = new Metrics.Timer("docManager.deleteComment")
callback = (args...) ->
timer.done()
_callback(args...)
DocumentManager.getDoc project_id, doc_id, (error, lines, version, ranges) ->
return callback(error) if error?
if !lines? or !version?
return callback(new Errors.NotFoundError("document not found: #{doc_id}"))
RangesManager.deleteComment comment_id, ranges, (error, new_ranges) ->
return callback(error) if error?
RedisManager.updateDocument doc_id, lines, version, [], new_ranges, (error) ->
return callback(error) if error?
callback()
2014-02-12 05:40:42 -05:00
getDocWithLock: (project_id, doc_id, callback = (error, lines, version) ->) ->
UpdateManager = require "./UpdateManager"
UpdateManager.lockUpdatesAndDo DocumentManager.getDoc, project_id, doc_id, callback
getDocAndRecentOpsWithLock: (project_id, doc_id, fromVersion, callback = (error, lines, version) ->) ->
UpdateManager = require "./UpdateManager"
UpdateManager.lockUpdatesAndDo DocumentManager.getDocAndRecentOps, project_id, doc_id, fromVersion, callback
setDocWithLock: (project_id, doc_id, lines, source, user_id, undoing, callback = (error) ->) ->
2014-02-12 05:40:42 -05:00
UpdateManager = require "./UpdateManager"
UpdateManager.lockUpdatesAndDo DocumentManager.setDoc, project_id, doc_id, lines, source, user_id, undoing, callback
2014-02-12 05:40:42 -05:00
flushDocIfLoadedWithLock: (project_id, doc_id, callback = (error) ->) ->
UpdateManager = require "./UpdateManager"
UpdateManager.lockUpdatesAndDo DocumentManager.flushDocIfLoaded, project_id, doc_id, callback
flushAndDeleteDocWithLock: (project_id, doc_id, callback = (error) ->) ->
UpdateManager = require "./UpdateManager"
UpdateManager.lockUpdatesAndDo DocumentManager.flushAndDeleteDoc, project_id, doc_id, callback
acceptChangeWithLock: (project_id, doc_id, change_id, callback = (error) ->) ->
UpdateManager = require "./UpdateManager"
UpdateManager.lockUpdatesAndDo DocumentManager.acceptChange, project_id, doc_id, change_id, callback
2017-01-24 09:57:11 -05:00
2017-05-04 10:32:54 -04:00
bulkAcceptChangesWithLock: (project_id, doc_id, change_ids, callback = (error) ->) ->
UpdateManager = require "./UpdateManager"
UpdateManager.lockUpdatesAndDo DocumentManager.bulkAcceptChanges, project_id, doc_id, change_ids, callback
2017-01-24 09:57:11 -05:00
deleteCommentWithLock: (project_id, doc_id, thread_id, callback = (error) ->) ->
UpdateManager = require "./UpdateManager"
UpdateManager.lockUpdatesAndDo DocumentManager.deleteComment, project_id, doc_id, thread_id, callback