-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsliding-window-breaker.ts
More file actions
59 lines (51 loc) · 1.74 KB
/
Copy pathsliding-window-breaker.ts
File metadata and controls
59 lines (51 loc) · 1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import type { ICircuitBreaker } from "../../domain/security/circuit-breaker";
import { createStructuredLogger } from "../../shared/structured-logger";
const log = createStructuredLogger({ component: "CircuitBreaker" });
/**
* Sliding-window circuit breaker.
* Tracks failures within a rolling time window and trips (opens) when failures
* exceed the configured threshold. Once open, it remains open until the window
* duration passes without new failures.
*
* Emits console warnings when tripping — OTLP span events should be wired
* at the caller level (AgentActor) for proper distributed tracing.
*/
export class SlidingWindowBreaker implements ICircuitBreaker {
private failures: number[] = [];
private threshold: number;
private windowMs: number;
private opened = false;
constructor(threshold: number, windowMs: number) {
this.threshold = threshold;
this.windowMs = windowMs;
}
recordSuccess(): void {
this.pruneOldFailures();
if (this.opened && this.failures.length < this.threshold) {
this.opened = false;
log.info("Circuit breaker closed — recovered");
}
}
recordFailure(): void {
this.failures.push(Date.now());
this.pruneOldFailures();
if (!this.opened && this.failures.length >= this.threshold) {
this.opened = true;
log.warn(
{ failures: this.failures.length, windowMs: this.windowMs },
"Circuit breaker OPEN",
);
}
}
isOpen(): boolean {
this.pruneOldFailures();
if (this.opened && this.failures.length < this.threshold) {
this.opened = false;
}
return this.opened;
}
private pruneOldFailures(): void {
const cutoff = Date.now() - this.windowMs;
this.failures = this.failures.filter((ts) => ts > cutoff);
}
}