semaphore-async-await
Advanced tools
Comparing version 1.2.2 to 1.3.0
/// <reference types="core-js" /> | ||
/** Class representing a semaphore | ||
* Semaphores are initialized with a number of permits that get aquired and released | ||
* over the lifecycle of the Semaphore. Functions can wait and stop executing until | ||
* a permit gets released (the method for which is called signal for historical reasons.) | ||
* over the lifecycle of the Semaphore. These permits limit the number of simultaneous | ||
* executions of the code that the Semaphore synchronizes. Functions can wait and stop | ||
* executing until a permit becomes available. | ||
* | ||
@@ -12,3 +13,3 @@ * Locks that only allow one execution of a critical section are a special case of | ||
* by functions that wait for permits to become available. This makes it possible | ||
* to use ES7 async/awaits to synchronize your code. | ||
* to use async/await to synchronize your code. | ||
*/ | ||
@@ -20,3 +21,3 @@ export default class Semaphore { | ||
* Creates a semaphore. | ||
* @param {number} permits The number of permits, i.e. things being allowed to run in parallel. | ||
* @param permits The number of permits, i.e. things being allowed to run in parallel. | ||
* To create a lock that only lets one thing run at a time, set this to 1. | ||
@@ -27,11 +28,15 @@ * This number can also be negative. | ||
/** | ||
* Returns a promise used to wait for a permit to become available. This method is supposed | ||
* to be awaited on. | ||
* @return {Promise} A promise that gets resolved when execution is allowed to proceed. | ||
* Returns a promise used to wait for a permit to become available. This method should be awaited on. | ||
* @returns A promise that gets resolved when execution is allowed to proceed. | ||
*/ | ||
wait(): Promise<boolean>; | ||
/** | ||
* Same as wait except the promise returned gets resolved with false if no permit becomes available in time. | ||
* @param {number} milliseconds The time spent waiting before the wait is aborted. | ||
* @return {Promise} A promise that gets resolved with true when execution is allowed to proceed or | ||
* Alias for {@linkcode Semaphore.wait}. | ||
* @returns A promise that gets resolved when execution is allowed to proceed. | ||
*/ | ||
acquire(): Promise<boolean>; | ||
/** | ||
* Same as {@linkcode Semaphore.wait} except the promise returned gets resolved with false if no permit becomes available in time. | ||
* @param milliseconds The time spent waiting before the wait is aborted. This is a lower bound, don't rely on it being precise. | ||
* @returns A promise that gets resolved with true when execution is allowed to proceed or | ||
* false if the time given elapses before a permit becomes available. | ||
@@ -42,8 +47,8 @@ */ | ||
* Synchronous function that tries to acquire a permit and returns true if successful, false otherwise. | ||
* @return {boolean} Whether a permit could be acquired. | ||
* @returns Whether a permit could be acquired. | ||
*/ | ||
tryAcquire(): boolean; | ||
/** | ||
* Acquires and returns all permits that are currently available | ||
* @return {number} Acquired permits. | ||
* Acquires all permits that are currently available and returns the number of acquired permits. | ||
* @returns Number of acquired permits. | ||
*/ | ||
@@ -57,7 +62,12 @@ drainPermits(): number; | ||
/** | ||
* Schedules func to be called once a permit becomes available. | ||
* @param {function} func - The function to be executed. | ||
* @return {T} A promise that gets resolved with the return value of the function. | ||
* A for {@linkcode Semaphore.signal}. | ||
*/ | ||
release(): void; | ||
/** | ||
* Schedules func to be called once a permit becomes available. Returns a promise that resolves to the return value of func. | ||
* @typeparam T The return type of func. | ||
* @param func The function to be executed. | ||
* @return A promise that gets resolved with the return value of the function. | ||
*/ | ||
execute<T>(func: () => T): Promise<T>; | ||
} |
@@ -39,4 +39,5 @@ "use strict"; | ||
* Semaphores are initialized with a number of permits that get aquired and released | ||
* over the lifecycle of the Semaphore. Functions can wait and stop executing until | ||
* a permit gets released (the method for which is called signal for historical reasons.) | ||
* over the lifecycle of the Semaphore. These permits limit the number of simultaneous | ||
* executions of the code that the Semaphore synchronizes. Functions can wait and stop | ||
* executing until a permit becomes available. | ||
* | ||
@@ -48,3 +49,3 @@ * Locks that only allow one execution of a critical section are a special case of | ||
* by functions that wait for permits to become available. This makes it possible | ||
* to use ES7 async/awaits to synchronize your code. | ||
* to use async/await to synchronize your code. | ||
*/ | ||
@@ -54,3 +55,3 @@ var Semaphore = (function () { | ||
* Creates a semaphore. | ||
* @param {number} permits The number of permits, i.e. things being allowed to run in parallel. | ||
* @param permits The number of permits, i.e. things being allowed to run in parallel. | ||
* To create a lock that only lets one thing run at a time, set this to 1. | ||
@@ -60,9 +61,8 @@ * This number can also be negative. | ||
function Semaphore(permits) { | ||
this.promiseResolverQueue = []; | ||
this.permits = permits; | ||
this.promiseResolverQueue = []; | ||
} | ||
/** | ||
* Returns a promise used to wait for a permit to become available. This method is supposed | ||
* to be awaited on. | ||
* @return {Promise} A promise that gets resolved when execution is allowed to proceed. | ||
* Returns a promise used to wait for a permit to become available. This method should be awaited on. | ||
* @returns A promise that gets resolved when execution is allowed to proceed. | ||
*/ | ||
@@ -84,5 +84,16 @@ Semaphore.prototype.wait = function () { | ||
/** | ||
* Same as wait except the promise returned gets resolved with false if no permit becomes available in time. | ||
* @param {number} milliseconds The time spent waiting before the wait is aborted. | ||
* @return {Promise} A promise that gets resolved with true when execution is allowed to proceed or | ||
* Alias for {@linkcode Semaphore.wait}. | ||
* @returns A promise that gets resolved when execution is allowed to proceed. | ||
*/ | ||
Semaphore.prototype.acquire = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.wait()]; | ||
}); | ||
}); | ||
}; | ||
/** | ||
* Same as {@linkcode Semaphore.wait} except the promise returned gets resolved with false if no permit becomes available in time. | ||
* @param milliseconds The time spent waiting before the wait is aborted. This is a lower bound, don't rely on it being precise. | ||
* @returns A promise that gets resolved with true when execution is allowed to proceed or | ||
* false if the time given elapses before a permit becomes available. | ||
@@ -125,3 +136,3 @@ */ | ||
* Synchronous function that tries to acquire a permit and returns true if successful, false otherwise. | ||
* @return {boolean} Whether a permit could be acquired. | ||
* @returns Whether a permit could be acquired. | ||
*/ | ||
@@ -136,4 +147,4 @@ Semaphore.prototype.tryAcquire = function () { | ||
/** | ||
* Acquires and returns all permits that are currently available | ||
* @return {number} Acquired permits. | ||
* Acquires all permits that are currently available and returns the number of acquired permits. | ||
* @returns Number of acquired permits. | ||
*/ | ||
@@ -168,6 +179,13 @@ Semaphore.prototype.drainPermits = function () { | ||
/** | ||
* Schedules func to be called once a permit becomes available. | ||
* @param {function} func - The function to be executed. | ||
* @return {T} A promise that gets resolved with the return value of the function. | ||
* A for {@linkcode Semaphore.signal}. | ||
*/ | ||
Semaphore.prototype.release = function () { | ||
this.signal(); | ||
}; | ||
/** | ||
* Schedules func to be called once a permit becomes available. Returns a promise that resolves to the return value of func. | ||
* @typeparam T The return type of func. | ||
* @param func The function to be executed. | ||
* @return A promise that gets resolved with the return value of the function. | ||
*/ | ||
Semaphore.prototype.execute = function (func) { | ||
@@ -174,0 +192,0 @@ return __awaiter(this, void 0, void 0, function () { |
{ | ||
"name": "semaphore-async-await", | ||
"version": "1.2.2", | ||
"version": "1.3.0", | ||
"author": { | ||
@@ -16,2 +16,3 @@ "name": "Jan Soendermann", | ||
"build": "tsc", | ||
"generate-docs": "typedoc --tsconfig ./tsconfig-typedoc.json --theme minimal --mode file --module system --out docs ./Semaphore.ts", | ||
"prepublish": "npm run build", | ||
@@ -29,4 +30,5 @@ "test": "node_modules/jasmine-es6/bin/jasmine.js" | ||
"tslint": "^4.1.0", | ||
"typedoc": "^0.5.1", | ||
"typescript": "^2.1.4" | ||
} | ||
} |
# JavaScript Semaphore | ||
A promise-based semaphore implementation suitable to be used with ES7 async/await. | ||
A promise-based semaphore implementation suitable to be used with async/await. | ||
## But JavaScript is single-threaded and doesn't need semaphores! | ||
This package can be used to synchronize functions that span multiple iterations of the event loop and prevent other code from being executed while your function is waiting for some event. | ||
This package can be used to synchronize functions that span multiple iterations of the event loop and prevent other code from being executed while your function is waiting. | ||
Suppose you have a function | ||
```javascript | ||
async function criticalFunction() { | ||
const data = await getDataFromDb(); | ||
const modifiedData = await asynchronouslyDoStuffWithData(data); | ||
await writeDataBackToDb(modifiedData); | ||
} | ||
``` | ||
Calling this function repeatedly could lead to overlapping read/writes. To avoid this problem, a lock can be added like so: | ||
```javascript | ||
const lock = new Semaphore(1); | ||
async function criticalFunction() { | ||
await lock.acquire(); | ||
const data = await getDataFromDb(); | ||
const modifiedData = await asynchronouslyDoStuffWithData(data); | ||
await writeDataBackToDb(modifiedData); | ||
lock.release(); | ||
} | ||
``` | ||
Asynchronous functions like ```criticalFunction``` are executed in multiple chunks of code on the event loop, this package makes it possible to enforce an ordering in these chunks. | ||
## Install | ||
```yarn add semaphore-async-await``` | ||
[<h2>API</h2>](http://jsoendermann.github.io/semaphore-async-await/classes/semaphore.html) | ||
## Usage | ||
@@ -69,29 +99,3 @@ ```javascript | ||
## Methods | ||
<dl> | ||
<dt><a href="#wait">Semaphore(permits)</a> ⇒ <code>Semaphore</code></dt> | ||
<dd><p>Creates a semaphore with the given number of permits, i.e. things being allowed to run in parallel. To create a lock that only lets one thing run at a time, give it one permit. This number can also be negative.</p> | ||
</dd> | ||
<dt><a href="#wait">wait()</a> ⇒ <code>Promise</code></dt> | ||
<dd><p>Returns a promise used to wait for a permit to become available.</p> | ||
</dd> | ||
<dt><a href="#waitFor">waitFor(milliseconds)</a> ⇒ <code>Promise</code></dt> | ||
<dd><p>Same as wait except the promise returned gets resolved with false if no permit becomes available in time.</p> | ||
</dd> | ||
<dt><a href="#tryAcquire">tryAcquire()</a> ⇒ <code>boolean</code></dt> | ||
<dd><p>Synchronous function that tries to acquire a permit and returns true if successful, false otherwise.</p> | ||
</dd> | ||
<dt><a href="#signal">signal()</a></dt> | ||
<dd><p>Increases the number of permits by one. If there are other functions waiting, one of them will | ||
continue to execute in a future iteration of the event loop.</p> | ||
</dd> | ||
<dt><a href="#execute">execute(func)</a> ⇒ <code>Promise</code></dt> | ||
<dd><p>Schedules func to be called once a permit becomes available. Returns a promise that resolves to the return value of the function.</p> | ||
</dd> | ||
</dl> | ||
## License | ||
MIT |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
17843
274
101
0
5
6