<commit_before>Settings = require('settings-sharelatex')
logger = require "logger-sharelatex"
Lockfile = require('lockfile') # from https://github.com/npm/lockfile
Errors = require "./Errors"
fs = require("fs")
Path = require("path")
module.exports = LockManager =
	LOCK_TEST_INTERVAL: 1000 # 50ms between each test of the lock
	MAX_LOCK_WAIT_TIME: 15000 # 10s maximum time to spend trying to get the lock
	LOCK_STALE: 5*60*1000 # 5 mins time until lock auto expires

	runWithLock: (path, runner = ((releaseLock = (error) ->) ->), callback = ((error) ->)) ->
		lockOpts =
			wait: @MAX_LOCK_WAIT_TIME
			pollPeriod: @LOCK_TEST_INTERVAL
			stale: @LOCK_STALE
		Lockfile.lock path, lockOpts, (error) ->
			return callback new Errors.AlreadyCompilingError("compile in progress")	if error?.code is 'EEXIST'
			fs.lstat path, (err, statLock)->
				fs.lstat Path.dirname(path), (err, statDir)->
					if error?
						logger.err error:error, path:path, statLock:statLock, statDir: statDir, "unable to get lock"
						return callback(error)
					runner (error1, args...) ->
						Lockfile.unlock path, (error2) ->
							error = error1 or error2
							return callback(error) if error?
							callback(null, args...)<commit_msg>improve error reporting<commit_after>Settings = require('settings-sharelatex')
logger = require "logger-sharelatex"
Lockfile = require('lockfile') # from https://github.com/npm/lockfile
Errors = require "./Errors"
fs = require("fs")
Path = require("path")
module.exports = LockManager =
	LOCK_TEST_INTERVAL: 1000 # 50ms between each test of the lock
	MAX_LOCK_WAIT_TIME: 15000 # 10s maximum time to spend trying to get the lock
	LOCK_STALE: 5*60*1000 # 5 mins time until lock auto expires

	runWithLock: (path, runner = ((releaseLock = (error) ->) ->), callback = ((error) ->)) ->
		lockOpts =
			wait: @MAX_LOCK_WAIT_TIME
			pollPeriod: @LOCK_TEST_INTERVAL
			stale: @LOCK_STALE
		Lockfile.lock path, lockOpts, (error) ->
			return callback new Errors.AlreadyCompilingError("compile in progress")	if error?.code is 'EEXIST'
				if error?
					fs.lstat path, (statLockErr, statLock)->
						fs.lstat Path.dirname(path), (statDirErr, statDir)->
							fs.readdir Path.dirname(path), (readdirErr, readdirDir)->
							logger.err error:error, path:path, statLock:statLock, statLockErr:statLockErr, statDir:statDir, statDirErr: statDirErr, readdirErr:readdirErr, readdirDir:readdirDir, "unable to get lock"
							return callback(error)
				else
					runner (error1, args...) ->
						Lockfile.unlock path, (error2) ->
							error = error1 or error2
							return callback(error) if error?
							callback(null, args...)
{'fraction_non_alphanumeric': 0.1244309559939302, 'fraction_numerical': 0.01896813353566009, 'mean_word_length': 4.022857142857143, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 22, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5603024', 'n_tokens_mistral': 1000, 'n_tokens_neox': 826, 'n_words': 238}