| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- const { promisify } = require('util')
- const OError = require('@overleaf/o-error')
- const Lockfile = require('lockfile')
- const Errors = require('./Errors')
- const fsPromises = require('fs/promises')
- const Path = require('path')
- const LOCK_OPTS = {
- pollPeriod: 1000, // 1s between each test of the lock
- wait: 15000, // 15s maximum time to spend trying to get the lock
- stale: 5 * 60 * 1000, // 5 mins time until lock auto expires
- }
- const PromisifiedLockfile = {
- lock: promisify(Lockfile.lock),
- unlock: promisify(Lockfile.unlock),
- }
- async function acquire(path) {
- try {
- await PromisifiedLockfile.lock(path, LOCK_OPTS)
- } catch (err) {
- if (err.code === 'EEXIST') {
- throw new Errors.AlreadyCompilingError('compile in progress')
- } else {
- const dir = Path.dirname(path)
- const [statLock, statDir, readdirDir] = await Promise.allSettled([
- fsPromises.lstat(path),
- fsPromises.lstat(dir),
- fsPromises.readdir(dir),
- ])
- OError.tag(err, 'unable to get lock', {
- statLock: unwrapPromiseResult(statLock),
- statDir: unwrapPromiseResult(statDir),
- readdirDir: unwrapPromiseResult(readdirDir),
- })
- throw err
- }
- }
- return new Lock(path)
- }
- class Lock {
- constructor(path) {
- this._path = path
- }
- async release() {
- await PromisifiedLockfile.unlock(this._path)
- }
- }
- function unwrapPromiseResult(result) {
- if (result.status === 'fulfilled') {
- return result.value
- } else {
- return result.reason
- }
- }
- module.exports = { acquire }
|