From 247d23647cb6f8aaf668505a6332d9b2a99064e9 Mon Sep 17 00:00:00 2001 From: Alisue Date: Tue, 24 Sep 2024 12:06:48 +0900 Subject: [PATCH] feat(Semaphore): add `lockedSize` to reveal the number of locked resources --- _raw_semaphore.ts | 7 +++++++ semaphore.ts | 7 +++++++ semaphore_test.ts | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/_raw_semaphore.ts b/_raw_semaphore.ts index 5833638..1af6e17 100644 --- a/_raw_semaphore.ts +++ b/_raw_semaphore.ts @@ -29,6 +29,13 @@ export class RawSemaphore { return this.#value === 0; } + /** + * Returns the number of currently locked operations. + */ + get lockedSize(): number { + return this.#resolves.length; + } + /** * Acquires the semaphore, blocking until the semaphore is available. */ diff --git a/semaphore.ts b/semaphore.ts index 80fd18a..407045e 100644 --- a/semaphore.ts +++ b/semaphore.ts @@ -35,6 +35,13 @@ export class Semaphore { return this.#sem.locked; } + /** + * Returns the number of currently locked operations. + */ + get lockedSize(): number { + return this.#sem.lockedSize; + } + /** * Acquires a lock on the semaphore, and invokes the specified function. * diff --git a/semaphore_test.ts b/semaphore_test.ts index 7081c74..8ed541c 100644 --- a/semaphore_test.ts +++ b/semaphore_test.ts @@ -106,3 +106,56 @@ test( assertThrows(() => new Semaphore(0), RangeError); }, ); + +test( + "Semaphore.lockedSize returns the number of locked operations (n=5)", + async () => { + const befores: number[] = []; + const afters: number[] = []; + const sem = new Semaphore(5); + const worker = (i: number) => { + return sem.lock(async () => { + befores.push(sem.lockedSize); + await new Promise((resolve) => setTimeout(resolve, 10 + i)); + afters.push(sem.lockedSize); + }); + }; + await Promise.all([...Array(10)].map((_, i) => worker(i))); + /** + * Worker 0 |5========5 + * Worker 1 |5=========4 + * Worker 2 |5==========3 + * Worker 3 |5===========2 + * Worker 4 |5============1 + * Worker 5 |----------4=============0 + * Worker 6 |-----------3==============0 + * Worker 7 |------------2===============0 + * Worker 8 |-------------1================0 + * Worker 9 |--------------0=================0 + */ + assertEquals(befores, [ + 5, + 5, + 5, + 5, + 5, + 4, + 3, + 2, + 1, + 0, + ]); + assertEquals(afters, [ + 5, + 4, + 3, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + ]); + }, +);