LockManager.coffee 1.3 KB

12345678910111213141516171819202122232425262728293031
  1. Settings = require('settings-sharelatex')
  2. logger = require "logger-sharelatex"
  3. Lockfile = require('lockfile') # from https://github.com/npm/lockfile
  4. Errors = require "./Errors"
  5. fs = require("fs")
  6. Path = require("path")
  7. module.exports = LockManager =
  8. LOCK_TEST_INTERVAL: 1000 # 50ms between each test of the lock
  9. MAX_LOCK_WAIT_TIME: 15000 # 10s maximum time to spend trying to get the lock
  10. LOCK_STALE: 5*60*1000 # 5 mins time until lock auto expires
  11. runWithLock: (path, runner = ((releaseLock = (error) ->) ->), callback = ((error) ->)) ->
  12. lockOpts =
  13. wait: @MAX_LOCK_WAIT_TIME
  14. pollPeriod: @LOCK_TEST_INTERVAL
  15. stale: @LOCK_STALE
  16. Lockfile.lock path, lockOpts, (error) ->
  17. if error?.code is 'EEXIST'
  18. return callback new Errors.AlreadyCompilingError("compile in progress")
  19. else if error?
  20. fs.lstat path, (statLockErr, statLock)->
  21. fs.lstat Path.dirname(path), (statDirErr, statDir)->
  22. fs.readdir Path.dirname(path), (readdirErr, readdirDir)->
  23. logger.err error:error, path:path, statLock:statLock, statLockErr:statLockErr, statDir:statDir, statDirErr: statDirErr, readdirErr:readdirErr, readdirDir:readdirDir, "unable to get lock"
  24. return callback(error)
  25. else
  26. runner (error1, args...) ->
  27. Lockfile.unlock path, (error2) ->
  28. error = error1 or error2
  29. return callback(error) if error?
  30. callback(null, args...)