Socket
Socket
Sign inDemoInstall

async-mutex

Package Overview
Dependencies
1
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.6 to 0.3.0

es6/errors.js

20

CHANGELOG.md
# Changelog
## 0.3.0
* Deprecate `Mutex::release` / `Semaphore::release` and remove them from the
documentation. The methods are still available in 0.3.x, but will be removed in
0.4.0.
I don't like breaking existing APIs, but using those methods is inherently
dangerous as they can accidentially release locks acquired in a completely
different place. Furthermore, they are mostly useless for semaphores. I consider
adding them an unfortunate mistake on my end.
A safe alternative is the usage of `runExclusive` which allows to execute
blocks exclusively and automatically manages acquiring and releasing the
mutex or semaphore.
* Add `Mutex::cancel` / `Semaphore::cancel` for rejecting all currently pending
locks.
* Add `tryAcquire` decorator for lock-or-fail semantics.
## 0.2.6
* Fix a nasty [bug](https://github.com/DirtyHairy/async-mutex/issues/27) related to
consecutive calls to `mutex::release`.
consecutive calls to `Mutex::release`.

@@ -8,0 +26,0 @@ ## 0.2.5

export { default as Mutex } from './Mutex';
export { default as Semaphore } from './Semaphore';
export { withTimeout } from './withTimeout';
export { tryAcquire } from './tryAcquire';
export * from './errors';

8

es6/Mutex.js
import { __awaiter, __generator } from "tslib";
import Semaphore from './Semaphore';
var Mutex = /** @class */ (function () {
function Mutex() {
this._semaphore = new Semaphore(1);
function Mutex(cancelError) {
this._semaphore = new Semaphore(1, cancelError);
}

@@ -26,7 +26,11 @@ Mutex.prototype.acquire = function () {

};
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
Mutex.prototype.release = function () {
this._semaphore.release();
};
Mutex.prototype.cancel = function () {
return this._semaphore.cancel();
};
return Mutex;
}());
export default Mutex;
import { __awaiter, __generator } from "tslib";
import { E_CANCELED } from './errors';
var Semaphore = /** @class */ (function () {
function Semaphore(_maxConcurrency) {
function Semaphore(_maxConcurrency, _cancelError) {
if (_cancelError === void 0) { _cancelError = E_CANCELED; }
this._maxConcurrency = _maxConcurrency;
this._cancelError = _cancelError;
this._queue = [];

@@ -14,6 +17,8 @@ if (_maxConcurrency <= 0) {

var locked = this.isLocked();
var ticket = new Promise(function (r) { return _this._queue.push(r); });
var ticketPromise = new Promise(function (resolve, reject) {
return _this._queue.push({ resolve: resolve, reject: reject });
});
if (!locked)
this._dispatch();
return ticket;
return ticketPromise;
};

@@ -44,5 +49,6 @@ Semaphore.prototype.runExclusive = function (callback) {

};
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
Semaphore.prototype.release = function () {
if (this._maxConcurrency > 1) {
throw new Error('this method is unavailabel on semaphores with concurrency > 1; use the scoped release returned by acquire instead');
throw new Error('this method is unavailable on semaphores with concurrency > 1; use the scoped release returned by acquire instead');
}

@@ -55,6 +61,11 @@ if (this._currentReleaser) {

};
Semaphore.prototype.cancel = function () {
var _this = this;
this._queue.forEach(function (ticket) { return ticket.reject(_this._cancelError); });
this._queue = [];
};
Semaphore.prototype._dispatch = function () {
var _this = this;
var nextConsumer = this._queue.shift();
if (!nextConsumer)
var nextTicket = this._queue.shift();
if (!nextTicket)
return;

@@ -69,3 +80,3 @@ var released = false;

};
nextConsumer([this._value--, this._currentReleaser]);
nextTicket.resolve([this._value--, this._currentReleaser]);
};

@@ -72,0 +83,0 @@ return Semaphore;

import { __awaiter, __generator } from "tslib";
import { E_TIMEOUT } from './errors';
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function withTimeout(sync, timeout, timeoutError) {
var _this = this;
if (timeoutError === void 0) { timeoutError = new Error('timeout'); }
if (timeoutError === void 0) { timeoutError = E_TIMEOUT; }
return {
acquire: function () {
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var isTimeout, ticket, release;
var isTimeout, handle, ticket, release, e_1;
return __generator(this, function (_a) {

@@ -14,8 +15,11 @@ switch (_a.label) {

isTimeout = false;
setTimeout(function () {
handle = setTimeout(function () {
isTimeout = true;
reject(timeoutError);
}, timeout);
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, sync.acquire()];
case 1:
case 2:
ticket = _a.sent();

@@ -29,3 +33,11 @@ if (isTimeout) {

}
return [2 /*return*/];
return [3 /*break*/, 4];
case 3:
e_1 = _a.sent();
if (!isTimeout) {
clearTimeout(handle);
reject(e_1);
}
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}

@@ -65,7 +77,11 @@ });

},
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
release: function () {
sync.release();
},
cancel: function () {
return sync.cancel();
},
isLocked: function () { return sync.isLocked(); },
};
}

@@ -6,1 +6,3 @@ export { default as Mutex } from './Mutex';

export { withTimeout } from './withTimeout';
export { tryAcquire } from './tryAcquire';
export * from './errors';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withTimeout = exports.Semaphore = exports.Mutex = void 0;
exports.tryAcquire = exports.withTimeout = exports.Semaphore = exports.Mutex = void 0;
var tslib_1 = require("tslib");
var Mutex_1 = require("./Mutex");

@@ -10,1 +11,4 @@ Object.defineProperty(exports, "Mutex", { enumerable: true, get: function () { return Mutex_1.default; } });

Object.defineProperty(exports, "withTimeout", { enumerable: true, get: function () { return withTimeout_1.withTimeout; } });
var tryAcquire_1 = require("./tryAcquire");
Object.defineProperty(exports, "tryAcquire", { enumerable: true, get: function () { return tryAcquire_1.tryAcquire; } });
tslib_1.__exportStar(require("./errors"), exports);
import MutexInterface from './MutexInterface';
declare class Mutex implements MutexInterface {
constructor(cancelError?: Error);
acquire(): Promise<MutexInterface.Releaser>;
runExclusive<T>(callback: MutexInterface.Worker<T>): Promise<T>;
isLocked(): boolean;
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
release(): void;
cancel(): void;
private _semaphore;
}
export default Mutex;

@@ -6,4 +6,4 @@ "use strict";

var Mutex = /** @class */ (function () {
function Mutex() {
this._semaphore = new Semaphore_1.default(1);
function Mutex(cancelError) {
this._semaphore = new Semaphore_1.default(1, cancelError);
}

@@ -29,7 +29,11 @@ Mutex.prototype.acquire = function () {

};
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
Mutex.prototype.release = function () {
this._semaphore.release();
};
Mutex.prototype.cancel = function () {
return this._semaphore.cancel();
};
return Mutex;
}());
exports.default = Mutex;

@@ -5,3 +5,5 @@ interface MutexInterface {

isLocked(): boolean;
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
release(): void;
cancel(): void;
}

@@ -8,0 +10,0 @@ declare namespace MutexInterface {

import SemaphoreInterface from './SemaphoreInterface';
declare class Semaphore implements SemaphoreInterface {
private _maxConcurrency;
constructor(_maxConcurrency: number);
private _cancelError;
constructor(_maxConcurrency: number, _cancelError?: Error);
acquire(): Promise<[number, SemaphoreInterface.Releaser]>;
runExclusive<T>(callback: SemaphoreInterface.Worker<T>): Promise<T>;
isLocked(): boolean;
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
release(): void;
cancel(): void;
private _dispatch;

@@ -10,0 +13,0 @@ private _queue;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var errors_1 = require("./errors");
var Semaphore = /** @class */ (function () {
function Semaphore(_maxConcurrency) {
function Semaphore(_maxConcurrency, _cancelError) {
if (_cancelError === void 0) { _cancelError = errors_1.E_CANCELED; }
this._maxConcurrency = _maxConcurrency;
this._cancelError = _cancelError;
this._queue = [];

@@ -16,6 +19,8 @@ if (_maxConcurrency <= 0) {

var locked = this.isLocked();
var ticket = new Promise(function (r) { return _this._queue.push(r); });
var ticketPromise = new Promise(function (resolve, reject) {
return _this._queue.push({ resolve: resolve, reject: reject });
});
if (!locked)
this._dispatch();
return ticket;
return ticketPromise;
};

@@ -46,5 +51,6 @@ Semaphore.prototype.runExclusive = function (callback) {

};
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
Semaphore.prototype.release = function () {
if (this._maxConcurrency > 1) {
throw new Error('this method is unavailabel on semaphores with concurrency > 1; use the scoped release returned by acquire instead');
throw new Error('this method is unavailable on semaphores with concurrency > 1; use the scoped release returned by acquire instead');
}

@@ -57,6 +63,11 @@ if (this._currentReleaser) {

};
Semaphore.prototype.cancel = function () {
var _this = this;
this._queue.forEach(function (ticket) { return ticket.reject(_this._cancelError); });
this._queue = [];
};
Semaphore.prototype._dispatch = function () {
var _this = this;
var nextConsumer = this._queue.shift();
if (!nextConsumer)
var nextTicket = this._queue.shift();
if (!nextTicket)
return;

@@ -71,3 +82,3 @@ var released = false;

};
nextConsumer([this._value--, this._currentReleaser]);
nextTicket.resolve([this._value--, this._currentReleaser]);
};

@@ -74,0 +85,0 @@ return Semaphore;

@@ -5,3 +5,5 @@ interface SemaphoreInterface {

isLocked(): boolean;
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
release(): void;
cancel(): void;
}

@@ -8,0 +10,0 @@ declare namespace SemaphoreInterface {

@@ -5,10 +5,11 @@ "use strict";

var tslib_1 = require("tslib");
var errors_1 = require("./errors");
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function withTimeout(sync, timeout, timeoutError) {
var _this = this;
if (timeoutError === void 0) { timeoutError = new Error('timeout'); }
if (timeoutError === void 0) { timeoutError = errors_1.E_TIMEOUT; }
return {
acquire: function () {
return new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var isTimeout, ticket, release;
var isTimeout, handle, ticket, release, e_1;
return tslib_1.__generator(this, function (_a) {

@@ -18,8 +19,11 @@ switch (_a.label) {

isTimeout = false;
setTimeout(function () {
handle = setTimeout(function () {
isTimeout = true;
reject(timeoutError);
}, timeout);
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, sync.acquire()];
case 1:
case 2:
ticket = _a.sent();

@@ -33,3 +37,11 @@ if (isTimeout) {

}
return [2 /*return*/];
return [3 /*break*/, 4];
case 3:
e_1 = _a.sent();
if (!isTimeout) {
clearTimeout(handle);
reject(e_1);
}
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}

@@ -69,5 +81,9 @@ });

},
/** @deprecated Deprecated in 0.3.0, will be removed in 0.4.0. Use runExclusive instead. */
release: function () {
sync.release();
},
cancel: function () {
return sync.cancel();
},
isLocked: function () { return sync.isLocked(); },

@@ -74,0 +90,0 @@ };

{
"name": "async-mutex",
"version": "0.2.6",
"version": "0.3.0",
"description": "A mutex for guarding async workflows",

@@ -58,17 +58,17 @@ "scripts": {

"@sinonjs/fake-timers": "^6.0.1",
"@types/mocha": "^8.0.4",
"@types/node": "^14.14.10",
"@types/mocha": "^8.2.0",
"@types/node": "^14.14.25",
"@types/sinonjs__fake-timers": "^6.0.2",
"@typescript-eslint/eslint-plugin": "^4.8.2",
"@typescript-eslint/parser": "^4.8.2",
"@typescript-eslint/eslint-plugin": "^4.14.2",
"@typescript-eslint/parser": "^4.14.2",
"coveralls": "^3.1.0",
"eslint": "^7.14.0",
"eslint": "^7.19.0",
"import-sort-style-eslint": "^6.0.0",
"mocha": "^8.2.1",
"nyc": "^15.1.0",
"prettier": "^2.2.0",
"prettier": "^2.2.1",
"prettier-plugin-import-sort": "^0.0.6",
"rollup": "^2.33.3",
"ts-node": "^9.0.0",
"typescript": "^4.1.2"
"rollup": "^2.38.5",
"ts-node": "^9.1.1",
"typescript": "^4.1.3"
},

@@ -87,4 +87,4 @@ "main": "lib/index.js",

"dependencies": {
"tslib": "^2.0.0"
"tslib": "^2.1.0"
}
}

@@ -1,3 +0,3 @@

[![Build Status](https://travis-ci.org/DirtyHairy/async-mutex.svg?branch=master)](https://travis-ci.org/DirtyHairy/async-mutex)
[![npm version](https://badge.fury.io/js/async-mutex.svg)](https://badge.fury.io/js/async-mutex)
[![Build status](https://github.com/DirtyHairy/async-mutex/workflows/Build%20and%20Tests/badge.svg)](https://github.com/DirtyHairy/async-mutex/actions?query=workflow%3A%22Build+and+Tests%22)
[![NPM version](https://badge.fury.io/js/async-mutex.svg)](https://badge.fury.io/js/async-mutex)
[![Coverage Status](https://coveralls.io/repos/github/DirtyHairy/async-mutex/badge.svg?branch=master)](https://coveralls.io/github/DirtyHairy/async-mutex?branch=master)

@@ -88,4 +88,2 @@

With the latest version of Node, native ES6 style imports are supported.
**TypeScript:**

@@ -96,2 +94,4 @@ ```typescript

With the latest version of Node, native ES6 style imports are supported.
## Mutex API

@@ -107,3 +107,3 @@

### Locking
### Synchronized code execution

@@ -113,5 +113,35 @@ Promise style:

mutex
.runExclusive(function() {
// ...
})
.then(function(result) {
// ...
});
```
async/await:
```typescript
await mutex.runExclusive(async () => {
// ...
});
```
`runExclusive` schedules the supplied callback to be run once the mutex is unlocked.
The function may return a promise. Once the promise is resolved or rejected (or immediately after
execution if an immediate value was returned),
the mutex is released. `runExclusive` returns a promise that adopts the state of the function result.
The mutex is released and the result rejected if an exception occurs during execution
if the callback.
### Manual locking / releasing
Promise style:
```typescript
mutex
.acquire()
.then(function(release) {
// ...
release();
});

@@ -131,3 +161,3 @@ ```

`acquire` returns an (ES6) promise that will resolve as soon as the mutex is
available and ready to be accessed. The promise resolves with a function `release` that
available. The promise resolves with a function `release` that
must be called once the mutex should be released again.

@@ -139,19 +169,32 @@

#### Alternate release API
`acquire` / `release` should be considered a low level API. In most situations,
`runExclusive` will be a better choice that automatically takes care of releasing
the mutex once a block of code has executed exclusively.
A locked mutex can also be released by calling the `release` method on the mutex. This will
release the current lock on the mutex.
### Checking whether the mutex is locked
**WARNING:** Using this API comes with the inherent danger of releasing a mutex locked
in an entirely unrelated place. Use with care.
```typescript
mutex.isLocked();
```
### Cancelling pending locks.
Pending locks can be cancelled by calling `cancel()` on the mutex. This will reject
all pending locks with `E_CANCELED`:
Promise style:
```typescript
import {E_CANCELED} from 'async-mutex';
mutex
.acquire()
.then(function() {
.runExclusive(() => {
// ...
// Please read and understand the WARNING above before using this API.
mutex.release();
})
.then(() => {
// ...
})
.catch(e => {
if (e === E_CANCELED) {
// ...
}
});

@@ -162,11 +205,39 @@ ```

```typescript
await mutex.acquire();
import {E_CANCELED} from 'async-mutex';
try {
// ...
} finally {
// Please read and understand the WARNING above before using this API.
mutex.release();
await mutex.runExclusive(() => {
// ...
});
} catch (e) {
if (e === E_CANCELED) {
// ...
}
}
```
This works with `aquire`, too:
if `acquire` is used for locking, the resulting promise will reject with `E_CANCELED`.
The error that is thrown can be customized by passing a different error to the `Mutex`
constructor:
```typescript
const mutex = new Mutex(new Error('fancy custom error'));
```
Note that while all pending locks are cancelled, a currently held lock will not be
revoked. In consequence, the mutex may not be available even after `cancel()` has been called.
## Semaphore API
### Creating
```typescript
const semaphore = new Semaphore(initialValue);
```
Creates a new semaphore. `initialValue` is a positive integer that defines the
initial value of the semaphore (aka the maximum number of concurrent consumers).
### Synchronized code execution

@@ -176,4 +247,4 @@

```typescript
mutex
.runExclusive(function() {
semaphore
.runExclusive(function(value) {
// ...

@@ -188,3 +259,3 @@ })

```typescript
await mutex.runExclusive(async () => {
await semaphore.runExclusive(async (value) => {
// ...

@@ -194,29 +265,13 @@ });

`runExclusive` schedules the supplied callback to be run once the mutex is unlocked.
`runExclusive` schedules the supplied callback to be run once the semaphore is available.
The callback will receive the current value of the semaphore as its argument.
The function may return a promise. Once the promise is resolved or rejected (or immediately after
execution if an immediate value was returned),
the mutex is released. `runExclusive` returns a promise that adopts the state of the function result.
the semaphore is released. `runExclusive` returns a promise that adopts the state of the function result.
The mutex is released and the result rejected if an exception occurs during execution
if the callback.
The semaphore is released and the result rejected if an exception occurs during execution
of the callback.
### Checking whether the mutex is locked
### Manual locking / releasing
```typescript
mutex.isLocked();
```
## Semaphore API
### Creating
```typescript
const semaphore = new Semaphore(initialValue);
```
Creates a new semaphore. `initialValue` is a positive integer that defines the
initial value of the semaphore (aka the maximum number of concurrent consumers)
### Locking
Promise style:

@@ -244,3 +299,3 @@ ```typescript

`acquire` returns an (ES6) promise that will resolve as soon as the semaphore is
available and ready to be accessed. The promise resolves to an array with the
available. The promise resolves to an array with the
first entry being the current value of the semaphore, and the second value a

@@ -254,44 +309,34 @@ function that must be called to release the semaphore once the critical operation

#### Alternate release API
`acquire` / `release` should be considered a low level API. In most situations,
`runExclusive` will be a better choice that automatically takes care of releasing
the mutex once a block of code has executed exclusively.
A locked semaphore can also be released by calling the `release` method on the semaphore.
This will release the most recent lock on the semaphore. As such, this will only work with
semaphores with `maxValue == 1`. Calling this on other semaphores will throw an exception.
### Checking whether the semaphore is locked
**WARNING:** Using this API comes with the inherent danger of releasing a semaphore locked
in an entirely unrelated place. Use with care.
Promise style:
```typescript
semaphore
.acquire()
.then(function([value]) {
// ...
// Please read and understand the WARNING above before using this API.
semaphore.release();
});
semaphore.isLocked();
```
async/await:
```typescript
const [value] = await semaphore.acquire();
try {
// ...
} finally {
// Please read and understand the WARNING above before using this API.
semaphore.release();
}
```
The semaphore is considered to be locked if it has a value of zero.
### Synchronized code execution
### Cancelling pending locks.
Pending locks can be cancelled by calling `cancel()` on the sempahore. This will reject
all pending locks with `E_CANCELED`:
Promise style:
```typescript
import {E_CANCELED} from 'async-mutex';
semaphore
.runExclusive(function(value) {
.runExclusive(() => {
// ...
})
.then(function(result) {
.then(() => {
// ...
})
.catch(e => {
if (e === E_CANCELED) {
// ...
}
});

@@ -302,23 +347,27 @@ ```

```typescript
await semaphore.runExclusive(async (value) => {
// ...
});
import {E_CANCELED} from 'async-mutex';
try {
await semaphore.runExclusive(() => {
// ...
});
} catch (e) {
if (e === E_CANCELED) {
// ...
}
}
```
`runExclusive` schedules the supplied callback to be run once the semaphore is available.
The callback will receive the current value of the semaphore as its argument.
The function may return a promise. Once the promise is resolved or rejected (or immediately after
execution if an immediate value was returned),
the semaphore is released. `runExclusive` returns a promise that adopts the state of the function result.
This works with `aquire`, too:
if `acquire` is used for locking, the resulting promise will reject with `E_CANCELED`.
The semaphore is released and the result rejected if an exception occurs during execution
if the callback.
The error that is thrown can be customized by passing a different error to the `Semaphore`
constructor:
### Checking whether the semaphore is locked
```typescript
semaphore.isLocked();
const semaphore = new Semaphore(2, new Error('fancy custom error'));
```
The semaphore is considered to be locked if it has a value of zero.
Note that while all pending locks are cancelled, any currently held locks will not be
revoked. In consequence, the semaphore may not be available even after `cancel()` has been called.

@@ -333,4 +382,6 @@ ## Limiting the time waiting for a mutex or semaphore to become available

```typescript
const mutexWithTimeout = withTimeout(new Mutex(), 100, new Error('timeout'));
const semaphoreWithTimeout = withTimeout(new Semaphore(5), 100, new Error('timeout'));
import {withTimeout, E_TIMEOUT} from 'asymc-mutex`;
const mutexWithTimeout = withTimeout(new Mutex(), 100);
const semaphoreWithTimeout = withTimeout(new Semaphore(5), 100);
```

@@ -340,6 +391,6 @@

The second argument of `withTimeout` is
the timeout in milliseconds. After the timeout is exceeded, the promise returned by
`acquire` and `runExclusive` will reject. The latter will not run the provided callback in
case of an timeout.
The second argument of `withTimeout` is the timeout in milliseconds. After the
timeout is exceeded, the promise returned by `acquire` and `runExclusive` will
reject with `E_TIMEOUT`. The latter will not run the provided callback in case
of an timeout.

@@ -349,4 +400,54 @@ The third argument of `withTimeout` is optional and can be used to

```typescript
const mutexWithTimeout = withTimeout(new Mutex(), 100, new Error('new fancy error'));
const semaphoreWithTimeout = withTimeout(new Semaphore(5), 100, new Error('new fancy error'));
```
### Failing early if the mutex or semaphore is not available
A shortcut exists for the case where you do not want to wait for a lock to
be available at all. The `tryAcquire` decorator can be applied to both mutexes
and semaphores and changes the behavior of `acquire` and `runExclusive` to
immediately throw `E_ALREADY_LOCKED` if the mutex is not available.
Promise style:
```typescript
import {tryAcquire, E_ALREADY_LOCKED} from 'asymc-mutex`;
tryAcquire(semaphoreOrMutex)
.runExclusive(() => {
// ...
})
.then(() => {
// ...
})
.catch(e => {
if (e === E_ALREADY_LOCKED) {
// ...
}
});
```
async/await:
```typescript
import {tryAcquire, E_ALREADY_LOCKED} from 'asymc-mutex`;
try {
await tryAcquire(semaphoreOrMutex).runExclusive(() => {
// ...
});
} catch (e) {
if (e === E_NOT_AVAILABLE {
// ...
}
}
```
Again, the error can be customized by providing a custom error as second argument to
`tryAcquire`.
# License
Feel free to use this library under the conditions of the MIT license.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc