UNPKG

@ayonli/jsext

Version:

A JavaScript extension package for building strong and modern applications.

106 lines (105 loc) 2.94 kB
/** * 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 {};