CompileManager.coffee 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. Settings = require('settings-sharelatex')
  2. redis = require("redis-sharelatex")
  3. rclient = redis.createClient(Settings.redis.web)
  4. DocumentUpdaterHandler = require "../DocumentUpdater/DocumentUpdaterHandler"
  5. Project = require("../../models/Project").Project
  6. ProjectRootDocManager = require "../Project/ProjectRootDocManager"
  7. ClsiManager = require "./ClsiManager"
  8. Metrics = require('../../infrastructure/Metrics')
  9. logger = require("logger-sharelatex")
  10. rateLimiter = require("../../infrastructure/RateLimiter")
  11. module.exports = CompileManager =
  12. compile: (project_id, user_id, opt = {}, _callback = (error) ->) ->
  13. timer = new Metrics.Timer("editor.compile")
  14. callback = (args...) ->
  15. timer.done()
  16. _callback(args...)
  17. @_checkIfAutoCompileLimitHasBeenHit opt.isAutoCompile, (err, canCompile)->
  18. if !canCompile
  19. return callback null, "autocompile-backoff", []
  20. logger.log project_id: project_id, user_id: user_id, "compiling project"
  21. CompileManager._checkIfRecentlyCompiled project_id, user_id, (error, recentlyCompiled) ->
  22. return callback(error) if error?
  23. if recentlyCompiled
  24. return callback new Error("project was recently compiled so not continuing")
  25. CompileManager._ensureRootDocumentIsSet project_id, (error) ->
  26. return callback(error) if error?
  27. DocumentUpdaterHandler.flushProjectToMongo project_id, (error) ->
  28. return callback(error) if error?
  29. ClsiManager.sendRequest project_id, opt.settingsOverride, (error, status, outputFiles) ->
  30. return callback(error) if error?
  31. logger.log files: outputFiles, "output files"
  32. callback(null, status, outputFiles)
  33. getLogLines: (project_id, callback)->
  34. Metrics.inc "editor.raw-logs"
  35. ClsiManager.getLogLines project_id, (error, logLines)->
  36. return callback(error) if error?
  37. callback null, logLines
  38. COMPILE_DELAY: 1 # seconds
  39. _checkIfRecentlyCompiled: (project_id, user_id, callback = (error, recentlyCompiled) ->) ->
  40. key = "compile:#{project_id}:#{user_id}"
  41. rclient.set key, true, "EX", @COMPILE_DELAY, "NX", (error, ok) ->
  42. return callback(error) if error?
  43. if ok == "OK"
  44. return callback null, false
  45. else
  46. return callback null, true
  47. _checkIfAutoCompileLimitHasBeenHit: (isAutoCompile, callback = (err, canCompile)->)->
  48. if !isAutoCompile
  49. return callback(null, true)
  50. opts =
  51. endpointName:"auto_compile"
  52. timeInterval:15
  53. subjectName:"everyone"
  54. throttle: 10
  55. rateLimiter.addCount opts, (err, canCompile)->
  56. if err?
  57. canCompile = false
  58. logger.log canCompile:canCompile, opts:opts, "checking if auto compile limit has been hit"
  59. callback err, canCompile
  60. _ensureRootDocumentIsSet: (project_id, callback = (error) ->) ->
  61. Project.findById project_id, 'rootDoc_id', (error, project)=>
  62. return callback(error) if error?
  63. if !project?
  64. return callback new Error("project not found")
  65. if project.rootDoc_id?
  66. callback()
  67. else
  68. ProjectRootDocManager.setRootDocAutomatically project_id, callback