1.0.0 • Published 10 months ago

@esfx/async-lockable v1.0.0

Weekly downloads
10
License
Apache-2.0
Repository
github
Last release
10 months ago

@esfx/async-lockable

A low-level Symbol-based common API for async coordination primitives.

Overview

Installation

npm i @esfx/async-lockable

Usage

import { AsyncLockable, LockHandle } from "@esfx/async-lockable";
import { Cancelable } from "@esfx/cancelable";
import { Disposable } from "@esfx/disposable";

export class MyLockable implements AsyncLockable {
    private _currentLock?: LockHandle<MyLockable>;

    async lock(cancelable?: Cancelable): Promise<LockHandle<MyLockable>> {
        const thisLock = this;
        return this._lock({
            // LockHandle implementation
            get mutex() {
                return thisLock;
            },
            get ownsLock() {
                return thisLock._currentLock === lockHandle;
            },

            async lock(cancelable?: Cancelable) {
                return thisLock._lock(lockHandle, cancelable);
            },

            unlock() {
                thisLock._unlock(lockHandle);
            },

            // AsyncLockable implementation
            [AsyncLockable.lock](cancelable?: Cancelable) {
                return this.lock(cancelable);
            },
            [AsyncLockable.unlock]() {
                this.unlock();
            },

            // Disposable implementation
            [Disposable.dispose]() {
                if (this.ownsLock) {
                    this.unlock();
                }
            }
        }, cancelable);
    }

    unlock() {
        if (!this._currentLock) throw new Error();
        this._unlock(this._currentLock);
    }

    private async _lock(lockHandle: LockHandle<MyLockable>, cancelable?: Cancelable) {
        if (this._currentLock === lockHandle) throw new Error();

        // ...perform actions necessary to take the lock...

        return this._currentLock = lockHandle;
    }

    private _unlock(lockHandle: LockHandle<MyLockable>) {
        if (this._currentLock !== lockHandle) throw new Error();

        // ...perform actions necessary to release lock...

    }

    // AsyncLockable implementation
    [AsyncLockable.lock](cancelable?: Cancelable) {
        return this.lock(cancelable);
    }

    [AsyncLockable.unlock]() {
        this.unlock();
    }
}

API

You can read more about the API here.