Skip to content

Commit cabd949

Browse files
rename Semaphore to CountingGovernor (#7)
1 parent 80b17ab commit cabd949

File tree

4 files changed

+15
-15
lines changed

4 files changed

+15
-15
lines changed

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ The concurrency control mechanism proposed here is also motivated by many other
1919

2020
## Proposal
2121

22-
This proposal consists of 3 major components: a Governor interface, the Semaphore class, and the AsyncIterator.prototype integration.
22+
This proposal consists of 3 major components: a Governor interface, the CountingGovernor class, and the AsyncIterator.prototype integration.
2323

2424
### Governor
2525

@@ -83,20 +83,20 @@ Similarly, `wrapIterator(it: Iterator<T> | AsyncIterator<T>): AsyncIterator<T>`
8383
- easy enough to live without it
8484
- alternative name: Regulator?
8585

86-
### Semaphore
86+
### CountingGovernor
8787

8888
This proposal subsumes Luca's [Semaphore proposal](https://github.com/lucacasonato/proposal-semaphore).
8989

90-
Semaphore is a [counting semaphore](https://en.wikipedia.org/wiki/Semaphore_%28programming%29) that implements the Governor interface and extends Governor. It can be given a non-negative integral Number *capacity* and it is responsible for ensuring that there are no more than that number of active GovernorTokens simultaneously.
90+
CountingGovernor is a [counting semaphore](https://en.wikipedia.org/wiki/Semaphore_%28programming%29) that implements the Governor interface and extends Governor. It can be given a non-negative integral Number *capacity* and it is responsible for ensuring that there are no more than that number of active GovernorTokens simultaneously.
9191

9292
#### Open Questions
9393

9494
- are idle listeners useful?
95-
- triggered whenever the Semaphore hits "full" capacity (0 active GovernorTokens)
95+
- triggered whenever the CountingGovernor hits "full" capacity (0 active GovernorTokens)
9696
- `addIdleListener(cb: () => void): void`
9797
- `removeIdleListener(cb: () => void): void`
9898
- callback interface or EventTarget?
99-
- are there concerns about sharing Semaphores across Agents?
99+
- are there concerns about sharing CountingGovernors across Agents?
100100
- alternative name: CountingGovernor? CountingRegulator?
101101

102102
### AsyncIterator.prototype integration
@@ -114,7 +114,7 @@ When not passed, these methods operate serially, as they do in the async iterato
114114

115115
This proposal also adds a `limit(governor)` method (the dual of `governor.wrapIterator(iterator)`) that returns a concurrency-limited AsyncIterator.
116116

117-
Because Semaphore will be an extremely commonly-used Governor, anywhere a Governor is accepted in any AsyncIterator.prototype method, a non-negative integral Number may be passed instead. It will be treated as if a Semaphore with that capacity was passed. Because of this, we are able to widen the first parameter of the `buffered` helper to accept a Governor in addition to the non-negative integral Number that it accepts as part of the async iterator helpers proposal.
117+
Because CountingGovernor will be an extremely commonly-used Governor, anywhere a Governor is accepted in any AsyncIterator.prototype method, a non-negative integral Number may be passed instead. It will be treated as if a CountingGovernor with that capacity was passed. Because of this, we are able to widen the first parameter of the `buffered` helper to accept a Governor in addition to the non-negative integral Number that it accepts as part of the async iterator helpers proposal.
118118

119119
#### Open Questions
120120

@@ -134,8 +134,8 @@ Because Semaphore will be an extremely commonly-used Governor, anywhere a Govern
134134
- `wrapIterator(it: Iterator<T> | AsyncIterator<T>): AsyncIterator<T>`
135135
- GovernorToken.prototype
136136
- `release(): void` === `[Symbol.dispose](): void`
137-
- Semaphores
138-
- `Semaphore(capacity: number)` constructor
137+
- CountingGovernors
138+
- `CountingGovernor(capacity: number)` constructor
139139
- extending Governor
140140
- implementing the Governor interface
141141
- shareable across threads
@@ -149,12 +149,12 @@ Because Semaphore will be an extremely commonly-used Governor, anywhere a Govern
149149

150150
### Why the generic Governor interface?
151151

152-
While a semaphore is a common concurrency control mechanism, there are many other ways to control concurrency. Some examples of these:
152+
While a counting semaphore is a common concurrency control mechanism, there are many other ways to control concurrency. Some examples of these:
153153

154154
- A governor that allows for a burst of activity before enforcing a limit (e.g. a semaphore that allows for 10 concurrent operations, but allows for 20 concurrent operations for the first 5 seconds).
155155
- A distributed governor that enforces a concurrency limit across multiple machines using a distributed lock or consensus algorithm.
156156
- A governor that enforces a concurrency limit based on the current load of the system (e.g. a semaphore that allows for 10 concurrent operations, but allows for 20 concurrent operations if the system is under 50% load).
157157

158158
Because of this variety of use cases, it is important to give developers the flexibility to use their own concurrency control mechanisms with built in JavaScript APIs.
159159

160-
The `Semaphore` class provides a simple and common concurrency control mechanism that can be used in many cases. It is expected that many developers will use `Semaphore` for their concurrency control needs. However, because APIs don't explicitly take a `Semaphore` instance, but any object that implements the `Governor` interface, developers can use their own concurrency control mechanisms if they need to.
160+
The `CountingGovernor` class provides a simple and common concurrency control mechanism that can be used in many cases. It is expected that many developers will use `CountingGovernor` for their concurrency control needs. However, because APIs don't explicitly take a `CountingGovernor` instance, but any object that implements the `Governor` interface, developers can use their own concurrency control mechanisms if they need to.

src/auto.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
import { Governor, Semaphore } from "./index.js";
2+
import { Governor, CountingGovernor } from "./index.js";
33

44
Object.defineProperty(globalThis, "Governor", {
55
configurable: true,
@@ -8,9 +8,9 @@ Object.defineProperty(globalThis, "Governor", {
88
value: Governor,
99
});
1010

11-
Object.defineProperty(globalThis, "Semaphore", {
11+
Object.defineProperty(globalThis, "CountingGovernor", {
1212
configurable: true,
1313
writable: true,
1414
enumerable: false,
15-
value: Semaphore,
15+
value: CountingGovernor,
1616
});

src/semaphore.ts renamed to src/counting-governor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Governor } from "./governor.js";
22

3-
export class Semaphore extends Governor {
3+
export class CountingGovernor extends Governor {
44
#capacity: number;
55
#acquired: number = 0;
66
#wait: PromiseWithResolvers<void> | null = null;

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export { Governor } from "./governor.js";
2-
export { Semaphore } from "./semaphore.js";
2+
export { CountingGovernor } from "./counting-governor.js";
33
export type { GovernorToken } from "./governor.ts";

0 commit comments

Comments
 (0)