@azure-tools/async-io
Version:
Asynchronous IO (for Azure Open Source Projects)
82 lines • 2.99 kB
JavaScript
;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Lock = exports.UnableToReadLockException = void 0;
const tasks_1 = require("@azure-tools/tasks");
const fs = require("fs");
const file_io_1 = require("./file-io");
/* eslint-disable */ // special case
const { lock, check, } = require('proper-lockfile');
const openInternal = tasks_1.promisify(fs.open);
class UnableToReadLockException extends tasks_1.Exception {
constructor(path, exitCode = 1) {
super(`Unable to create read lock on '${path}'.`, exitCode);
this.exitCode = exitCode;
Object.setPrototypeOf(this, UnableToReadLockException.prototype);
}
}
exports.UnableToReadLockException = UnableToReadLockException;
class Lock {
static async exclusive(path, options) {
return tasks_1.promisify(await this._exclusive(path, options));
}
static async waitForExclusive(path, timeout = 5 * 60 * 1000) {
let result = null;
const expire = Date.now() + timeout;
do {
try {
result = await this.exclusive(path);
}
catch (e) {
// no worries. Just wait a few seconds and see if we can get it.
await tasks_1.Delay(3000);
}
} while (result == null && expire > Date.now());
return result;
}
static async read(path, options) {
// first try to create the file
// it's ok if it fails
options = options || {};
options.delay = options.delay || 2000;
options.retries = options.retries || 4;
const p = `${path}.lock`;
try {
fs.writeFileSync(p, 'lockfile');
}
catch (e) {
// no worries.
}
// try to open the file for read
try {
if (await file_io_1.isFile(p)) {
const fd = await openInternal(p, 'r');
return async () => {
fs.close(fd, (err) => { });
try {
fs.unlinkSync(p);
}
catch (_a) {
// ignore errors
}
};
}
}
catch (_a) {
// ignore errors
}
if (options.retries) {
await tasks_1.Delay(options.delay);
options.retries--;
return this.read(path, options);
}
throw new UnableToReadLockException(path);
}
}
exports.Lock = Lock;
Lock._exclusive = tasks_1.promisify(lock);
Lock.check = tasks_1.promisify(check);
//# sourceMappingURL=lock.js.map