@azure-tools/extension
Version:
Yarn-Based extension aquisition (for Azure Open Source Projects)
68 lines • 2.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncLock = void 0;
const tasks_1 = require("@azure-tools/tasks");
/**
* Lock using promises to await on lock.
*/
class AsyncLock {
/**
* @constructor - Creates an instance of a CriticalSection
*
* @param name - a cosmetic name for the 'resource'. Note: multiple CriticalSection instances with the same do not offer exclusivity, it's tied to the object instance.
*/
constructor(name = "unnamed") {
this.name = name;
}
/**
* Asynchronously acquires the lock. Will wait for up {@link timeoutMS} milliseconds
* @throws ExclusiveLockUnavailableException - if the timeout is reached before the lock can be acquired.
* @param timeoutMS - the length of time in miliiseconds to wait for a lock.
* @returns - the release function to release the lock.
*/
async acquire(timeoutMS = 20000, name) {
const timeout = createTimeout(timeoutMS);
if (this.promise !== undefined) {
const waitForPromise = async () => {
while (this.promise !== undefined) {
await this.promise;
}
};
await Promise.race([waitForPromise(), timeout.promise]);
}
// check to see if the promise is still around, which indicates
// that we must have timed out.
if (this.promise) {
throw new tasks_1.ExclusiveLockUnavailableException(this.name, timeoutMS);
}
// Stop the timeout so it doesn't keep a pending Promise around.
timeout.cancel();
let resolvePromise;
let released = false;
this.promise = new Promise((resolve) => {
resolvePromise = resolve;
});
// the release function is returned to the consumer
return () => {
if (!released) {
released = true;
this.promise = undefined;
resolvePromise();
}
};
}
}
exports.AsyncLock = AsyncLock;
function createTimeout(delayMS) {
let timeout;
const promise = new Promise((res) => {
timeout = setTimeout(res, delayMS);
});
return {
promise,
cancel: () => {
clearTimeout(timeout);
},
};
}
//# sourceMappingURL=async-lock.js.map