Skip to content

Commit 2312098

Browse files
docs(async/unstable): document known race condition in circuit breaker
1 parent 1383bd8 commit 2312098

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

async/unstable_circuit_breaker.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,30 @@ export class CircuitBreaker<T = unknown> {
431431
* @returns The result of the operation.
432432
* @throws {CircuitBreakerOpenError} If circuit is open.
433433
*/
434+
/*
435+
* NOTE: Known race condition in half-open state concurrent tracking.
436+
*
437+
* The `halfOpenInFlight` counter uses a read-modify-write pattern that is
438+
* not atomic. Under high concurrency, more requests than `halfOpenMaxConcurrent`
439+
* may slip through.
440+
*
441+
* Future fix: Once `@std/async/unstable-semaphore` stabilizes, use it to
442+
* guard state transitions:
443+
*
444+
* ```ts
445+
* import { Semaphore } from "@std/async/semaphore";
446+
*
447+
* #stateMutex = new Semaphore(1);
448+
*
449+
* async execute<R extends T>(fn: () => Promise<R>): Promise<R> {
450+
* {
451+
* using _lock = await this.#stateMutex.acquire();
452+
* // Check state and acquire half-open slot atomically
453+
* }
454+
* // Execute fn() outside the lock
455+
* }
456+
* ```
457+
*/
434458
async execute<R extends T>(fn: () => Promise<R>): Promise<R> {
435459
const currentTime = Date.now();
436460
const currentState = this.#resolveCurrentState();

0 commit comments

Comments
 (0)