LockManager.coffee 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. Settings = require "settings-sharelatex"
  2. redis = require("redis-sharelatex")
  3. rclient = redis.createClient(Settings.redis.web)
  4. module.exports = LockManager =
  5. LOCK_TEST_INTERVAL: 50 # 50ms between each test of the lock
  6. MAX_LOCK_WAIT_TIME: 10000 # 10s maximum time to spend trying to get the lock
  7. LOCK_TTL: 10 # seconds
  8. tryLock : (key, callback = (err, gotLock) ->) ->
  9. rclient.set key, "locked", "EX", @LOCK_TTL, "NX", (err, gotLock)->
  10. return callback(err) if err?
  11. if gotLock == "OK"
  12. callback err, true
  13. else
  14. callback err, false
  15. getLock: (key, callback = (error) ->) ->
  16. startTime = Date.now()
  17. do attempt = () ->
  18. if Date.now() - startTime > LockManager.MAX_LOCK_WAIT_TIME
  19. return callback(new Error("Timeout"))
  20. LockManager.tryLock key, (error, gotLock) ->
  21. return callback(error) if error?
  22. if gotLock
  23. callback(null)
  24. else
  25. setTimeout attempt, LockManager.LOCK_TEST_INTERVAL
  26. checkLock: (key, callback = (err, isFree) ->) ->
  27. rclient.exists key, (err, exists) ->
  28. return callback(err) if err?
  29. exists = parseInt exists
  30. if exists == 1
  31. callback err, false
  32. else
  33. callback err, true
  34. releaseLock: (key, callback) ->
  35. rclient.del key, callback
  36. runWithLock: (key, runner = ( (releaseLock = (error) ->) -> ), callback = ( (error) -> )) ->
  37. LockManager.getLock key, (error) ->
  38. return callback(error) if error?
  39. runner (error1) ->
  40. LockManager.releaseLock key, (error2) ->
  41. error = error1 or error2
  42. return callback(error) if error?
  43. callback()