@ayonli/jsext
Version:
A JavaScript extension package for building strong and modern applications.
106 lines (105 loc) • 2.94 kB
TypeScript
/**
* A mutual exclusion mechanism for concurrent operations and protecting shared
* data.
* @module
*/
declare const _queue: unique symbol;
declare const _value: unique symbol;
declare const _mutex: unique symbol;
declare const _unlocked: unique symbol;
/**
* Mutual Exclusion prevents multiple coroutines from accessing the same shared
* resource simultaneously.
*
* **NOTE:**
* Currently, the Mutex instance can not be used across multiple threads, but is
* considering adding support for `parallel` threads.
*
* @example
* ```ts
* import { Mutex } from "@ayonli/jsext/lock";
* import { random } from "@ayonli/jsext/number";
* import { sleep } from "@ayonli/jsext/async";
*
* const mutex = new Mutex(1);
*
* async function concurrentOperation() {
* using shared = await mutex.lock();
* const value1 = shared.value;
*
* await otherAsyncOperations();
*
* shared.value += 1
* const value2 = shared.value;
*
* // Without mutex lock, the shared value may have been modified by other
* // calls during `await otherAsyncOperation()`, and the following
* // assertion will fail.
* console.assert(value1 + 1 === value2);
* }
*
* async function otherAsyncOperations() {
* await sleep(100 * random(1, 10));
* }
*
* await Promise.all([
* concurrentOperation(),
* concurrentOperation(),
* concurrentOperation(),
* concurrentOperation(),
* ]);
* ```
*/
export declare class Mutex<T> {
private [_queue];
private [_value];
/**
* @param value The data associated to the mutex instance.
*/
constructor(value: T);
/**
* Acquires the lock of the mutex, optionally for modifying the shared
* resource.
*/
lock(): Promise<Mutex.Lock<T>>;
}
export declare namespace Mutex {
abstract class Lock<T> {
private [_mutex];
private [_unlocked];
constructor(mutex: Mutex<T>);
/** Accesses the data associated to the mutex instance. */
get value(): T;
set value(v: T);
/** Releases the current lock of the mutex. */
unlock(): void;
[Symbol.dispose](): void;
}
}
/**
* Acquires a mutex lock for the given key in order to perform concurrent
* operations and prevent conflicts.
*
* If the key is currently being locked by other coroutines, this function will
* block until the lock becomes available again.
*
* @example
* ```ts
* import lock from "@ayonli/jsext/lock";
*
* const key = "lock_key";
*
* export async function concurrentOperation() {
* using ctx = await lock(key);
* void ctx;
*
* // This block will never be run if there are other coroutines holding
* // the lock.
* //
* // Other coroutines trying to lock the same key will also never be run
* // before this function completes.
* }
* ```
*/
export default function lock(key: any): Promise<Mutex.Lock<undefined>>;
export {};