PersistenceManager.coffee 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. request = require "request"
  2. Settings = require "settings-sharelatex"
  3. Errors = require "./Errors"
  4. Metrics = require "./Metrics"
  5. {db, ObjectId} = require("./mongojs")
  6. logger = require "logger-sharelatex"
  7. # We have to be quick with HTTP calls because we're holding a lock that
  8. # expires after 30 seconds. We can't let any errors in the rest of the stack
  9. # hold us up, and need to bail out quickly if there is a problem.
  10. MAX_HTTP_REQUEST_LENGTH = 5000 # 5 seconds
  11. module.exports = PersistenceManager =
  12. getDoc: (project_id, doc_id, callback = (error, lines, version) ->) ->
  13. PersistenceManager.getDocFromWeb project_id, doc_id, (error, lines) ->
  14. return callback(error) if error?
  15. PersistenceManager.getDocVersionInMongo doc_id, (error, version) ->
  16. return callback(error) if error?
  17. callback null, lines, version
  18. setDoc: (project_id, doc_id, lines, version, callback = (error) ->) ->
  19. PersistenceManager.setDocInWeb project_id, doc_id, lines, (error) ->
  20. return callback(error) if error?
  21. PersistenceManager.setDocVersionInMongo doc_id, version, (error) ->
  22. return callback(error) if error?
  23. callback()
  24. getDocFromWeb: (project_id, doc_id, _callback = (error, lines) ->) ->
  25. timer = new Metrics.Timer("persistenceManager.getDoc")
  26. callback = (args...) ->
  27. timer.done()
  28. _callback(args...)
  29. url = "#{Settings.apis.web.url}/project/#{project_id}/doc/#{doc_id}"
  30. request {
  31. url: url
  32. method: "GET"
  33. headers:
  34. "accept": "application/json"
  35. auth:
  36. user: Settings.apis.web.user
  37. pass: Settings.apis.web.pass
  38. sendImmediately: true
  39. jar: false
  40. timeout: MAX_HTTP_REQUEST_LENGTH
  41. }, (error, res, body) ->
  42. return callback(error) if error?
  43. if res.statusCode >= 200 and res.statusCode < 300
  44. try
  45. body = JSON.parse body
  46. catch e
  47. return callback(e)
  48. return callback null, body.lines
  49. else if res.statusCode == 404
  50. return callback(new Errors.NotFoundError("doc not not found: #{url}"))
  51. else
  52. return callback(new Error("error accessing web API: #{url} #{res.statusCode}"))
  53. setDocInWeb: (project_id, doc_id, lines, _callback = (error) ->) ->
  54. timer = new Metrics.Timer("persistenceManager.setDoc")
  55. callback = (args...) ->
  56. timer.done()
  57. _callback(args...)
  58. url = "#{Settings.apis.web.url}/project/#{project_id}/doc/#{doc_id}"
  59. request {
  60. url: url
  61. method: "POST"
  62. body: JSON.stringify
  63. lines: lines
  64. headers:
  65. "content-type": "application/json"
  66. auth:
  67. user: Settings.apis.web.user
  68. pass: Settings.apis.web.pass
  69. sendImmediately: true
  70. jar: false
  71. timeout: MAX_HTTP_REQUEST_LENGTH
  72. }, (error, res, body) ->
  73. return callback(error) if error?
  74. if res.statusCode >= 200 and res.statusCode < 300
  75. return callback null
  76. else if res.statusCode == 404
  77. return callback(new Errors.NotFoundError("doc not not found: #{url}"))
  78. else
  79. return callback(new Error("error accessing web API: #{url} #{res.statusCode}"))
  80. getDocVersionInMongo: (doc_id, callback = (error, version) ->) ->
  81. db.docOps.find {
  82. doc_id: ObjectId(doc_id)
  83. }, {
  84. version: 1
  85. }, (error, docs) ->
  86. return callback(error) if error?
  87. if docs.length < 1 or !docs[0].version?
  88. return callback null, 0
  89. else
  90. return callback null, docs[0].version
  91. setDocVersionInMongo: (doc_id, version, callback = (error) ->) ->
  92. db.docOps.update {
  93. doc_id: ObjectId(doc_id)
  94. }, {
  95. $set: version: version
  96. }, {
  97. upsert: true
  98. }, callback