DispatchManager.coffee 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. Settings = require('settings-sharelatex')
  2. logger = require('logger-sharelatex')
  3. Keys = require('./UpdateKeys')
  4. redis = require("redis-sharelatex")
  5. Errors = require("./Errors")
  6. UpdateManager = require('./UpdateManager')
  7. Metrics = require('./Metrics')
  8. RateLimitManager = require('./RateLimitManager')
  9. module.exports = DispatchManager =
  10. createDispatcher: (RateLimiter) ->
  11. client = redis.createClient(Settings.redis.documentupdater)
  12. worker = {
  13. client: client
  14. _waitForUpdateThenDispatchWorker: (callback = (error) ->) ->
  15. timer = new Metrics.Timer "worker.waiting"
  16. worker.client.blpop "pending-updates-list", 0, (error, result) ->
  17. timer.done()
  18. return callback(error) if error?
  19. return callback() if !result?
  20. [list_name, doc_key] = result
  21. [project_id, doc_id] = Keys.splitProjectIdAndDocId(doc_key)
  22. # Dispatch this in the background
  23. backgroundTask = (cb) ->
  24. UpdateManager.processOutstandingUpdatesWithLock project_id, doc_id, (error) ->
  25. # log everything except OpRangeNotAvailable errors, these are normal
  26. if error?
  27. # downgrade OpRangeNotAvailable and "Delete component" errors so they are not sent to sentry
  28. logAsWarning = (error instanceof Errors.OpRangeNotAvailableError) || ((typeof error is' string') && error.match(/^Delete component/))
  29. if logAsWarning
  30. logger.warn err: error, project_id: project_id, doc_id: doc_id, "error processing update"
  31. else
  32. logger.error err: error, project_id: project_id, doc_id: doc_id, "error processing update"
  33. cb()
  34. RateLimiter.run backgroundTask, callback
  35. run: () ->
  36. return if Settings.shuttingDown
  37. worker._waitForUpdateThenDispatchWorker (error) =>
  38. if error?
  39. logger.error err: error, "Error in worker process"
  40. throw error
  41. else
  42. worker.run()
  43. }
  44. return worker
  45. createAndStartDispatchers: (number) ->
  46. RateLimiter = new RateLimitManager(number)
  47. for i in [1..number]
  48. worker = DispatchManager.createDispatcher(RateLimiter)
  49. worker.run()