UpdatesManager.coffee 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. MongoManager = require "./MongoManager"
  2. RedisManager = require "./RedisManager"
  3. UpdateCompressor = require "./UpdateCompressor"
  4. LockManager = require "./LockManager"
  5. logger = require "logger-sharelatex"
  6. module.exports = UpdatesManager =
  7. compressAndSaveRawUpdates: (doc_id, rawUpdates, callback = (error) ->) ->
  8. length = rawUpdates.length
  9. if length == 0
  10. return callback()
  11. MongoManager.popLastCompressedUpdate doc_id, (error, lastCompressedUpdate) ->
  12. return callback(error) if error?
  13. logger.log doc_id: doc_id, "popped last update"
  14. # Ensure that raw updates start where lastCompressedUpdate left off
  15. if lastCompressedUpdate?
  16. rawUpdates = rawUpdates.slice(0)
  17. while rawUpdates[0]? and rawUpdates[0].v <= lastCompressedUpdate.v
  18. rawUpdates.shift()
  19. if rawUpdates[0]? and rawUpdates[0].v != lastCompressedUpdate.v + 1
  20. error = new Error("Tried to apply raw op at version #{rawUpdates[0].v} to last compressed update with version #{lastCompressedUpdate.v}")
  21. logger.error err: error, doc_id: doc_id, "inconsistent doc versions"
  22. # Push the update back into Mongo - catching errors at this
  23. # point is useless, we're already bailing
  24. MongoManager.insertCompressedUpdates doc_id, [lastCompressedUpdate], () ->
  25. return callback error
  26. return
  27. compressedUpdates = UpdateCompressor.compressRawUpdates lastCompressedUpdate, rawUpdates
  28. MongoManager.insertCompressedUpdates doc_id, compressedUpdates, (error) ->
  29. return callback(error) if error?
  30. logger.log doc_id: doc_id, rawUpdatesLength: length, compressedUpdatesLength: compressedUpdates.length, "compressed doc updates"
  31. callback()
  32. REDIS_READ_BATCH_SIZE: 100
  33. processUncompressedUpdates: (doc_id, callback = (error) ->) ->
  34. logger.log "processUncompressedUpdates"
  35. RedisManager.getOldestRawUpdates doc_id, UpdatesManager.REDIS_READ_BATCH_SIZE, (error, rawUpdates) ->
  36. return callback(error) if error?
  37. length = rawUpdates.length
  38. logger.log doc_id: doc_id, length: length, "got raw updates from redis"
  39. UpdatesManager.compressAndSaveRawUpdates doc_id, rawUpdates, (error) ->
  40. return callback(error) if error?
  41. logger.log doc_id: doc_id, "compressed and saved doc updates"
  42. RedisManager.deleteOldestRawUpdates doc_id, length, (error) ->
  43. return callback(error) if error?
  44. if length == UpdatesManager.REDIS_READ_BATCH_SIZE
  45. # There might be more updates
  46. logger.log doc_id: doc_id, "continuing processing updates"
  47. setTimeout () ->
  48. UpdatesManager.processUncompressedUpdates doc_id, callback
  49. , 0
  50. else
  51. logger.log doc_id: doc_id, "all raw updates processed"
  52. callback()
  53. processUncompressedUpdatesWithLock: (doc_id, callback = (error) ->) ->
  54. LockManager.runWithLock(
  55. "HistoryLock:#{doc_id}",
  56. (releaseLock) ->
  57. UpdatesManager.processUncompressedUpdates doc_id, releaseLock
  58. callback
  59. )
  60. getUpdates: (doc_id, options = {}, callback = (error, updates) ->) ->
  61. UpdatesManager.processUncompressedUpdatesWithLock doc_id, (error) ->
  62. return callback(error) if error?
  63. MongoManager.getUpdates doc_id, options, callback