DispatchManager.coffee 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  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.realtime)
  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. logger.log("getting pending-updates-list", error, result)
  18. timer.done()
  19. return callback(error) if error?
  20. return callback() if !result?
  21. [list_name, doc_key] = result
  22. [project_id, doc_id] = Keys.splitProjectIdAndDocId(doc_key)
  23. # Dispatch this in the background
  24. backgroundTask = (cb) ->
  25. UpdateManager.processOutstandingUpdatesWithLock project_id, doc_id, (error) ->
  26. # log everything except OpRangeNotAvailable errors, these are normal
  27. if error?
  28. # downgrade OpRangeNotAvailable and "Delete component" errors so they are not sent to sentry
  29. logAsWarning = (error instanceof Errors.OpRangeNotAvailableError) || (error instanceof Errors.DeleteMismatchError)
  30. if logAsWarning
  31. logger.warn err: error, project_id: project_id, doc_id: doc_id, "error processing update"
  32. else
  33. logger.error err: error, project_id: project_id, doc_id: doc_id, "error processing update"
  34. cb()
  35. RateLimiter.run backgroundTask, callback
  36. run: () ->
  37. return if Settings.shuttingDown
  38. worker._waitForUpdateThenDispatchWorker (error) =>
  39. if error?
  40. logger.error err: error, "Error in worker process"
  41. throw error
  42. else
  43. worker.run()
  44. }
  45. return worker
  46. createAndStartDispatchers: (number) ->
  47. RateLimiter = new RateLimitManager(number)
  48. for i in [1..number]
  49. worker = DispatchManager.createDispatcher(RateLimiter)
  50. worker.run()