DocumentManager.coffee 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. RedisManager = require "./RedisManager"
  2. PersistenceManager = require "./PersistenceManager"
  3. DocOpsManager = require "./DocOpsManager"
  4. DiffCodec = require "./DiffCodec"
  5. logger = require "logger-sharelatex"
  6. Metrics = require "./Metrics"
  7. module.exports = DocumentManager =
  8. getDoc: (project_id, doc_id, _callback = (error, lines, version) ->) ->
  9. timer = new Metrics.Timer("docManager.getDoc")
  10. callback = (args...) ->
  11. timer.done()
  12. _callback(args...)
  13. RedisManager.getDoc doc_id, (error, lines, version) ->
  14. return callback(error) if error?
  15. if !lines? or !version?
  16. logger.log project_id: project_id, doc_id: doc_id, "doc not in redis so getting from persistence API"
  17. PersistenceManager.getDoc project_id, doc_id, (error, lines, version) ->
  18. return callback(error) if error?
  19. logger.log project_id: project_id, doc_id: doc_id, lines: lines, version: version, "got doc from persistence API"
  20. RedisManager.putDocInMemory project_id, doc_id, lines, version, (error) ->
  21. return callback(error) if error?
  22. callback null, lines, version
  23. else
  24. callback null, lines, version
  25. getDocAndRecentOps: (project_id, doc_id, fromVersion, _callback = (error, lines, version, recentOps) ->) ->
  26. timer = new Metrics.Timer("docManager.getDocAndRecentOps")
  27. callback = (args...) ->
  28. timer.done()
  29. _callback(args...)
  30. DocumentManager.getDoc project_id, doc_id, (error, lines, version) ->
  31. return callback(error) if error?
  32. if fromVersion == -1
  33. callback null, lines, version, []
  34. else
  35. DocOpsManager.getPreviousDocOps project_id, doc_id, fromVersion, version, (error, ops) ->
  36. return callback(error) if error?
  37. callback null, lines, version, ops
  38. setDoc: (project_id, doc_id, newLines, source, user_id, _callback = (error) ->) ->
  39. timer = new Metrics.Timer("docManager.setDoc")
  40. callback = (args...) ->
  41. timer.done()
  42. _callback(args...)
  43. if !newLines?
  44. return callback(new Error("No lines were provided to setDoc"))
  45. UpdateManager = require "./UpdateManager"
  46. DocumentManager.getDoc project_id, doc_id, (error, oldLines, version) ->
  47. return callback(error) if error?
  48. if oldLines? and oldLines.length > 0 and oldLines[0].text?
  49. logger.log doc_id: doc_id, project_id: project_id, oldLines: oldLines, newLines: newLines, "document is JSON so not updating"
  50. return callback(null)
  51. logger.log doc_id: doc_id, project_id: project_id, oldLines: oldLines, newLines: newLines, "setting a document via http"
  52. DiffCodec.diffAsShareJsOp oldLines, newLines, (error, op) ->
  53. return callback(error) if error?
  54. update =
  55. doc: doc_id
  56. op: op
  57. v: version
  58. meta:
  59. type: "external"
  60. source: source
  61. user_id: user_id
  62. UpdateManager.applyUpdates project_id, doc_id, [update], (error) ->
  63. return callback(error) if error?
  64. DocumentManager.flushDocIfLoaded project_id, doc_id, (error) ->
  65. return callback(error) if error?
  66. callback null
  67. flushDocIfLoaded: (project_id, doc_id, _callback = (error) ->) ->
  68. timer = new Metrics.Timer("docManager.flushDocIfLoaded")
  69. callback = (args...) ->
  70. timer.done()
  71. _callback(args...)
  72. RedisManager.getDoc doc_id, (error, lines, version) ->
  73. return callback(error) if error?
  74. if !lines? or !version?
  75. logger.log project_id: project_id, doc_id: doc_id, "doc is not loaded so not flushing"
  76. callback null
  77. else
  78. logger.log project_id: project_id, doc_id: doc_id, version: version, "flushing doc"
  79. PersistenceManager.setDoc project_id, doc_id, lines, version, (error) ->
  80. return callback(error) if error?
  81. callback null
  82. flushAndDeleteDoc: (project_id, doc_id, _callback = (error) ->) ->
  83. timer = new Metrics.Timer("docManager.flushAndDeleteDoc")
  84. callback = (args...) ->
  85. timer.done()
  86. _callback(args...)
  87. DocumentManager.flushDocIfLoaded project_id, doc_id, (error) ->
  88. return callback(error) if error?
  89. # We should flush pending ops to track-changes here but this is
  90. # already done in the real-time WebsocketController.leaveProject
  91. # method so we leave it there. Note, if you ever add the flush
  92. # in here be sure to do it in the background because it can take
  93. # a long time.
  94. RedisManager.removeDocFromMemory project_id, doc_id, (error) ->
  95. return callback(error) if error?
  96. callback null
  97. getDocWithLock: (project_id, doc_id, callback = (error, lines, version) ->) ->
  98. UpdateManager = require "./UpdateManager"
  99. UpdateManager.lockUpdatesAndDo DocumentManager.getDoc, project_id, doc_id, callback
  100. getDocAndRecentOpsWithLock: (project_id, doc_id, fromVersion, callback = (error, lines, version) ->) ->
  101. UpdateManager = require "./UpdateManager"
  102. UpdateManager.lockUpdatesAndDo DocumentManager.getDocAndRecentOps, project_id, doc_id, fromVersion, callback
  103. setDocWithLock: (project_id, doc_id, lines, source, user_id, callback = (error) ->) ->
  104. UpdateManager = require "./UpdateManager"
  105. UpdateManager.lockUpdatesAndDo DocumentManager.setDoc, project_id, doc_id, lines, source, user_id, callback
  106. flushDocIfLoadedWithLock: (project_id, doc_id, callback = (error) ->) ->
  107. UpdateManager = require "./UpdateManager"
  108. UpdateManager.lockUpdatesAndDo DocumentManager.flushDocIfLoaded, project_id, doc_id, callback
  109. flushAndDeleteDocWithLock: (project_id, doc_id, callback = (error) ->) ->
  110. UpdateManager = require "./UpdateManager"
  111. UpdateManager.lockUpdatesAndDo DocumentManager.flushAndDeleteDoc, project_id, doc_id, callback