2014-02-12 05:23:40 -05:00
|
|
|
request = require 'request'
|
|
|
|
request = request.defaults()
|
|
|
|
settings = require 'settings-sharelatex'
|
|
|
|
_ = require 'underscore'
|
|
|
|
async = require 'async'
|
|
|
|
logger = require('logger-sharelatex')
|
2017-04-03 11:18:30 -04:00
|
|
|
metrics = require('metrics-sharelatex')
|
2014-09-26 09:52:00 -04:00
|
|
|
redis = require("redis-sharelatex")
|
|
|
|
rclient = redis.createClient(settings.redis.web)
|
2014-02-12 05:23:40 -05:00
|
|
|
Project = require("../../models/Project").Project
|
|
|
|
ProjectLocator = require('../../Features/Project/ProjectLocator')
|
|
|
|
|
2014-06-18 11:37:18 -04:00
|
|
|
module.exports = DocumentUpdaterHandler =
|
2014-02-12 05:23:40 -05:00
|
|
|
|
2014-10-15 09:11:02 -04:00
|
|
|
queueChange : (project_id, doc_id, change, callback = ()->)->
|
2014-02-12 05:23:40 -05:00
|
|
|
jsonChange = JSON.stringify change
|
2014-08-07 08:19:10 -04:00
|
|
|
doc_key = keys.combineProjectIdAndDocId(project_id, doc_id)
|
|
|
|
multi = rclient.multi()
|
|
|
|
multi.rpush keys.pendingUpdates(doc_id:doc_id), jsonChange
|
|
|
|
multi.sadd keys.docsWithPendingUpdates, doc_key
|
|
|
|
multi.rpush "pending-updates-list", doc_key
|
|
|
|
multi.exec (error) ->
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(error) if error?
|
2014-08-07 08:19:10 -04:00
|
|
|
callback()
|
2014-02-12 05:23:40 -05:00
|
|
|
|
2014-10-15 09:11:02 -04:00
|
|
|
flushProjectToMongo: (project_id, callback = (error) ->)->
|
|
|
|
logger.log project_id:project_id, "flushing project from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
timer = new metrics.Timer("flushing.mongo.project")
|
|
|
|
url = "#{settings.apis.documentupdater.url}/project/#{project_id}/flush"
|
|
|
|
request.post url, (error, res, body)->
|
|
|
|
if error?
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.error err: error, project_id: project_id, "error flushing project from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(error)
|
|
|
|
else if res.statusCode >= 200 and res.statusCode < 300
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.log project_id: project_id, "flushed project from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(null)
|
|
|
|
else
|
|
|
|
error = new Error("document updater returned a failure status code: #{res.statusCode}")
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.error err: error, project_id: project_id, "document updater returned failure status code: #{res.statusCode}"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(error)
|
|
|
|
|
2014-06-18 11:37:18 -04:00
|
|
|
flushMultipleProjectsToMongo: (project_ids, callback = (error) ->) ->
|
|
|
|
jobs = []
|
|
|
|
for project_id in project_ids
|
|
|
|
do (project_id) ->
|
|
|
|
jobs.push (callback) ->
|
|
|
|
DocumentUpdaterHandler.flushProjectToMongo project_id, callback
|
|
|
|
async.series jobs, callback
|
|
|
|
|
2014-10-15 09:11:02 -04:00
|
|
|
flushProjectToMongoAndDelete: (project_id, callback = ()->) ->
|
|
|
|
logger.log project_id:project_id, "deleting project from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
timer = new metrics.Timer("delete.mongo.project")
|
|
|
|
url = "#{settings.apis.documentupdater.url}/project/#{project_id}"
|
|
|
|
request.del url, (error, res, body)->
|
|
|
|
if error?
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.error err: error, project_id: project_id, "error deleting project from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(error)
|
|
|
|
else if res.statusCode >= 200 and res.statusCode < 300
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.log project_id: project_id, "deleted project from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(null)
|
|
|
|
else
|
|
|
|
error = new Error("document updater returned a failure status code: #{res.statusCode}")
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.error err: error, project_id: project_id, "document updater returned failure status code: #{res.statusCode}"
|
2014-05-08 10:47:50 -04:00
|
|
|
return callback(error)
|
|
|
|
|
|
|
|
flushDocToMongo: (project_id, doc_id, callback = (error) ->) ->
|
|
|
|
logger.log project_id:project_id, doc_id: doc_id, "flushing doc from document updater"
|
|
|
|
timer = new metrics.Timer("flushing.mongo.doc")
|
|
|
|
url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}/flush"
|
|
|
|
request.post url, (error, res, body)->
|
|
|
|
if error?
|
|
|
|
logger.error err: error, project_id: project_id, doc_id: doc_id, "error flushing doc from document updater"
|
|
|
|
return callback(error)
|
|
|
|
else if res.statusCode >= 200 and res.statusCode < 300
|
|
|
|
logger.log project_id: project_id, doc_id: doc_id, "flushed doc from document updater"
|
|
|
|
return callback(null)
|
|
|
|
else
|
|
|
|
error = new Error("document updater returned a failure status code: #{res.statusCode}")
|
|
|
|
logger.error err: error, project_id: project_id, doc_id: doc_id, "document updater returned failure status code: #{res.statusCode}"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(error)
|
|
|
|
|
2014-10-15 09:11:02 -04:00
|
|
|
deleteDoc : (project_id, doc_id, callback = ()->)->
|
|
|
|
logger.log project_id:project_id, doc_id: doc_id, "deleting doc from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
timer = new metrics.Timer("delete.mongo.doc")
|
|
|
|
url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}"
|
|
|
|
request.del url, (error, res, body)->
|
|
|
|
if error?
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.error err: error, project_id: project_id, doc_id: doc_id, "error deleting doc from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(error)
|
|
|
|
else if res.statusCode >= 200 and res.statusCode < 300
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.log project_id: project_id, doc_id: doc_id, "deleted doc from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(null)
|
|
|
|
else
|
|
|
|
error = new Error("document updater returned a failure status code: #{res.statusCode}")
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.error err: error, project_id: project_id, doc_id: doc_id, "document updater returned failure status code: #{res.statusCode}"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(error)
|
|
|
|
|
2016-12-08 09:09:06 -05:00
|
|
|
getDocument: (project_id, doc_id, fromVersion, callback = (error, doclines, version, ranges, ops) ->) ->
|
2014-02-12 05:23:40 -05:00
|
|
|
timer = new metrics.Timer("get-document")
|
|
|
|
url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}?fromVersion=#{fromVersion}"
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.log project_id:project_id, doc_id: doc_id, "getting doc from document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
request.get url, (error, res, body)->
|
|
|
|
timer.done()
|
|
|
|
if error?
|
|
|
|
logger.error err:error, url:url, project_id:project_id, doc_id:doc_id, "error getting doc from doc updater"
|
|
|
|
return callback(error)
|
|
|
|
if res.statusCode >= 200 and res.statusCode < 300
|
|
|
|
logger.log project_id:project_id, doc_id:doc_id, "got doc from document document updater"
|
|
|
|
try
|
|
|
|
body = JSON.parse(body)
|
|
|
|
catch error
|
|
|
|
return callback(error)
|
2016-12-08 09:09:06 -05:00
|
|
|
callback null, body.lines, body.version, body.ranges, body.ops
|
2014-02-12 05:23:40 -05:00
|
|
|
else
|
|
|
|
logger.error project_id:project_id, doc_id:doc_id, url: url, "doc updater returned a non-success status code: #{res.statusCode}"
|
|
|
|
callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
|
|
|
|
|
2016-02-04 09:26:50 -05:00
|
|
|
setDocument : (project_id, doc_id, user_id, docLines, source, callback = (error) ->)->
|
2014-02-12 05:23:40 -05:00
|
|
|
timer = new metrics.Timer("set-document")
|
|
|
|
url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}"
|
|
|
|
body =
|
|
|
|
url: url
|
|
|
|
json:
|
|
|
|
lines: docLines
|
2014-10-15 11:37:14 -04:00
|
|
|
source: source
|
2016-02-04 09:26:50 -05:00
|
|
|
user_id: user_id
|
|
|
|
logger.log project_id:project_id, doc_id: doc_id, source: source, user_id: user_id, "setting doc in document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
request.post body, (error, res, body)->
|
|
|
|
timer.done()
|
|
|
|
if error?
|
|
|
|
logger.error err:error, url:url, project_id:project_id, doc_id:doc_id, "error setting doc in doc updater"
|
|
|
|
return callback(error)
|
|
|
|
if res.statusCode >= 200 and res.statusCode < 300
|
2014-10-15 09:11:02 -04:00
|
|
|
logger.log project_id: project_id, doc_id: doc_id, "set doc in document updater"
|
2014-02-12 05:23:40 -05:00
|
|
|
return callback(null)
|
|
|
|
else
|
|
|
|
logger.error project_id:project_id, doc_id:doc_id, url: url, "doc updater returned a non-success status code: #{res.statusCode}"
|
|
|
|
callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
|
|
|
|
|
2017-01-09 09:25:27 -05:00
|
|
|
acceptChange: (project_id, doc_id, change_id, callback = (error) ->) ->
|
|
|
|
timer = new metrics.Timer("accept-change")
|
|
|
|
url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}/change/#{change_id}/accept"
|
|
|
|
logger.log {project_id, doc_id, change_id}, "accepting change in document updater"
|
|
|
|
request.post url, (error, res, body)->
|
|
|
|
timer.done()
|
|
|
|
if error?
|
|
|
|
logger.error {err:error, project_id, doc_id, change_id}, "error accepting change in doc updater"
|
|
|
|
return callback(error)
|
|
|
|
if res.statusCode >= 200 and res.statusCode < 300
|
|
|
|
logger.log {project_id, doc_id, change_id}, "accepted change in document updater"
|
|
|
|
return callback(null)
|
|
|
|
else
|
|
|
|
logger.error {project_id, doc_id, change_id}, "doc updater returned a non-success status code: #{res.statusCode}"
|
|
|
|
callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
|
2014-02-12 05:23:40 -05:00
|
|
|
|
2017-01-24 10:18:49 -05:00
|
|
|
deleteThread: (project_id, doc_id, thread_id, callback = (error) ->) ->
|
|
|
|
timer = new metrics.Timer("delete-thread")
|
|
|
|
url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}/comment/#{thread_id}"
|
|
|
|
logger.log {project_id, doc_id, thread_id}, "deleting comment range in document updater"
|
|
|
|
request.del url, (error, res, body)->
|
|
|
|
timer.done()
|
|
|
|
if error?
|
|
|
|
logger.error {err:error, project_id, doc_id, thread_id}, "error deleting comment range in doc updater"
|
|
|
|
return callback(error)
|
|
|
|
if res.statusCode >= 200 and res.statusCode < 300
|
|
|
|
logger.log {project_id, doc_id, thread_id}, "deleted comment rangee in document updater"
|
|
|
|
return callback(null)
|
|
|
|
else
|
|
|
|
logger.error {project_id, doc_id, thread_id}, "doc updater returned a non-success status code: #{res.statusCode}"
|
|
|
|
callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
|
|
|
|
|
2014-02-12 05:23:40 -05:00
|
|
|
PENDINGUPDATESKEY = "PendingUpdates"
|
|
|
|
DOCLINESKEY = "doclines"
|
|
|
|
DOCIDSWITHPENDINGUPDATES = "DocsWithPendingUpdates"
|
|
|
|
|
|
|
|
keys =
|
|
|
|
pendingUpdates : (op) -> "#{PENDINGUPDATESKEY}:#{op.doc_id}"
|
|
|
|
docsWithPendingUpdates: DOCIDSWITHPENDINGUPDATES
|
|
|
|
docLines : (op) -> "#{DOCLINESKEY}:#{op.doc_id}"
|
|
|
|
combineProjectIdAndDocId: (project_id, doc_id) -> "#{project_id}:#{doc_id}"
|
|
|
|
|
|
|
|
|