Skip to content

Commit 7a8c10b

Browse files
committed
feat(Semaphore): add waiterCount to reveal the number of lock waiters
1 parent c4ec010 commit 7a8c10b

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

_raw_semaphore.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ export class RawSemaphore {
2929
return this.#value === 0;
3030
}
3131

32+
/**
33+
* Returns the number of waiters that are waiting for lock release.
34+
*/
35+
get waiterCount(): number {
36+
return this.#resolves.length;
37+
}
38+
3239
/**
3340
* Acquires the semaphore, blocking until the semaphore is available.
3441
*/

semaphore.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ export class Semaphore {
3535
return this.#sem.locked;
3636
}
3737

38+
/**
39+
* Returns the number of waiters that are waiting for lock release.
40+
*/
41+
get waiterCount(): number {
42+
return this.#sem.waiterCount;
43+
}
44+
3845
/**
3946
* Acquires a lock on the semaphore, and invokes the specified function.
4047
*

semaphore_test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,56 @@ test(
106106
assertThrows(() => new Semaphore(0), RangeError);
107107
},
108108
);
109+
110+
test(
111+
"Semaphore.waiterCount returns the number of waiters (n=5)",
112+
async () => {
113+
const befores: number[] = [];
114+
const afters: number[] = [];
115+
const sem = new Semaphore(5);
116+
const worker = (i: number) => {
117+
return sem.lock(async () => {
118+
befores.push(sem.waiterCount);
119+
await new Promise((resolve) => setTimeout(resolve, 10 + i));
120+
afters.push(sem.waiterCount);
121+
});
122+
};
123+
await Promise.all([...Array(10)].map((_, i) => worker(i)));
124+
/**
125+
* Worker 0 |5========5
126+
* Worker 1 |5=========4
127+
* Worker 2 |5==========3
128+
* Worker 3 |5===========2
129+
* Worker 4 |5============1
130+
* Worker 5 |----------4=============0
131+
* Worker 6 |-----------3==============0
132+
* Worker 7 |------------2===============0
133+
* Worker 8 |-------------1================0
134+
* Worker 9 |--------------0=================0
135+
*/
136+
assertEquals(befores, [
137+
5,
138+
5,
139+
5,
140+
5,
141+
5,
142+
4,
143+
3,
144+
2,
145+
1,
146+
0,
147+
]);
148+
assertEquals(afters, [
149+
5,
150+
4,
151+
3,
152+
2,
153+
1,
154+
0,
155+
0,
156+
0,
157+
0,
158+
0,
159+
]);
160+
},
161+
);

0 commit comments

Comments
 (0)