ProjectManager.coffee 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. RedisManager = require "./RedisManager"
  2. DocumentManager = require "./DocumentManager"
  3. async = require "async"
  4. logger = require "logger-sharelatex"
  5. Metrics = require "./Metrics"
  6. Errors = require "./Errors"
  7. module.exports = ProjectManager =
  8. flushProjectWithLocks: (project_id, _callback = (error) ->) ->
  9. timer = new Metrics.Timer("projectManager.flushProjectWithLocks")
  10. callback = (args...) ->
  11. timer.done()
  12. _callback(args...)
  13. RedisManager.getDocIdsInProject project_id, (error, doc_ids) ->
  14. return callback(error) if error?
  15. jobs = []
  16. errors = []
  17. for doc_id in (doc_ids or [])
  18. do (doc_id) ->
  19. jobs.push (callback) ->
  20. DocumentManager.flushDocIfLoadedWithLock project_id, doc_id, (error) ->
  21. if error?
  22. logger.error err: error, project_id: project_id, doc_id: doc_id, "error flushing doc"
  23. errors.push(error)
  24. callback()
  25. logger.log project_id: project_id, doc_ids: doc_ids, "flushing docs"
  26. async.series jobs, () ->
  27. if errors.length > 0
  28. callback new Error("Errors flushing docs. See log for details")
  29. else
  30. callback(null)
  31. flushAndDeleteProjectWithLocks: (project_id, _callback = (error) ->) ->
  32. timer = new Metrics.Timer("projectManager.flushAndDeleteProjectWithLocks")
  33. callback = (args...) ->
  34. timer.done()
  35. _callback(args...)
  36. RedisManager.getDocIdsInProject project_id, (error, doc_ids) ->
  37. return callback(error) if error?
  38. jobs = []
  39. errors = []
  40. for doc_id in (doc_ids or [])
  41. do (doc_id) ->
  42. jobs.push (callback) ->
  43. DocumentManager.flushAndDeleteDocWithLock project_id, doc_id, (error) ->
  44. if error?
  45. logger.error err: error, project_id: project_id, doc_id: doc_id, "error deleting doc"
  46. errors.push(error)
  47. callback()
  48. logger.log project_id: project_id, doc_ids: doc_ids, "deleting docs"
  49. async.series jobs, () ->
  50. if errors.length > 0
  51. callback new Error("Errors deleting docs. See log for details")
  52. else
  53. callback(null)
  54. getProjectDocs: (project_id, projectStateHash, excludeVersions = {}, _callback = (error, docs) ->) ->
  55. timer = new Metrics.Timer("projectManager.getProjectDocs")
  56. callback = (args...) ->
  57. timer.done()
  58. _callback(args...)
  59. RedisManager.checkOrSetProjectState project_id, projectStateHash, (error, projectStateChanged) ->
  60. if error?
  61. logger.error err: error, project_id: project_id, "error getting/setting project state in getProjectDocs"
  62. return callback(error)
  63. # we can't return docs if project structure has changed
  64. return callback Errors.ProjectStateChangedError("project state changed") if projectStateChanged
  65. # project structure hasn't changed, return doc content from redis
  66. RedisManager.getDocIdsInProject project_id, (error, doc_ids) ->
  67. if error?
  68. logger.error err: error, project_id: project_id, "error getting doc ids in getProjectDocs"
  69. return callback(error)
  70. jobs = []
  71. docs = []
  72. for doc_id in doc_ids or []
  73. do (doc_id) ->
  74. jobs.push (cb) ->
  75. # check the doc version first
  76. RedisManager.getDocVersion doc_id, (error, version) ->
  77. if error?
  78. logger.error err: error, project_id: project_id, doc_id: doc_id, "error getting project doc version in getProjectDocs"
  79. return cb(error)
  80. # skip getting the doc if we already have that version
  81. if version? and version is excludeVersions[doc_id]
  82. # not currently using excludeVersions so we shouldn't get here!
  83. # change to logger.log when this code path is in use
  84. logger.error err: error, project_id: project_id, doc_id: doc_id, version: version, "skipping doc version in getProjectDocs"
  85. return cb()
  86. # otherwise get the doc lines from redis
  87. RedisManager.getDocLines doc_id, (error, lines) ->
  88. if error?
  89. logger.error err: error, project_id: project_id, doc_id: doc_id, "error getting project doc lines in getProjectDocs"
  90. return cb(error)
  91. try
  92. docs.push {_id: doc_id, lines: JSON.parse(lines), v: version}
  93. catch e
  94. logger.error err: e, project_id: project_id, doc_id: doc_id, lines: lines, version: version, "error parsing doc lines in getProjectDocs"
  95. return cb(e)
  96. cb()
  97. async.series jobs, (error) ->
  98. return callback(error) if error?
  99. callback(null, docs)