@microsoft.azure/async-io
Version:
Promisify'd asnyc wrappers (for Azure Open Source Projects)
79 lines • 2.83 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 });
const fs = require("fs");
const promisify = require("pify");
const tasks_1 = require("@microsoft.azure/tasks");
const file_io_1 = require("./file-io");
const { lock, check, } = require("proper-lockfile");
const fs_open = 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 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 fs_open(p, 'r');
return async () => {
fs.close(fd, (err) => { });
try {
fs.unlinkSync(p);
}
catch (E) {
}
};
}
}
catch (e) {
}
if (options.retries) {
await tasks_1.Delay(options.delay);
options.retries--;
return await this.read(path, options);
}
throw new UnableToReadLockException(path);
}
}
Lock._exclusive = promisify(lock);
Lock.check = promisify(check);
exports.Lock = Lock;
//# sourceMappingURL=lock.js.map