Skip to content

Commit 1c1d2e7

Browse files
committed
feat: add event loop block notifications and env flag
Add colored console warnings when the event loop is blocked and wire a feature flag to enable/disable notifications- Introduce notifyEventLoopBlocked() in eventLoopMonitor.server.ts to log a colored warning with blocked and async type. - Call notifyEventLoopBlocked() when an event-loop stall is detected. - Add EVENT_LOOP_MONITOR_NOTIFY_ENABLED to env schema with a default of "0" so notifications are off by default. This makes it easier to spot long event-loop stalls during development or when notifications are explicitly enabled.
1 parent 47bed15 commit 1c1d2e7

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

apps/webapp/app/env.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,7 @@ const EnvironmentSchema = z
12601260
EVENT_LOOP_MONITOR_THRESHOLD_MS: z.coerce.number().int().default(100),
12611261
EVENT_LOOP_MONITOR_UTILIZATION_INTERVAL_MS: z.coerce.number().int().default(1000),
12621262
EVENT_LOOP_MONITOR_UTILIZATION_SAMPLE_RATE: z.coerce.number().default(0.05),
1263+
EVENT_LOOP_MONITOR_NOTIFY_ENABLED: z.string().default("0"),
12631264

12641265
VERY_SLOW_QUERY_THRESHOLD_MS: z.coerce.number().int().optional(),
12651266

apps/webapp/app/eventLoopMonitor.server.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@ import { signalsEmitter } from "./services/signals.server";
99

1010
const THRESHOLD_NS = env.EVENT_LOOP_MONITOR_THRESHOLD_MS * 1e6;
1111

12+
// ANSI color codes for terminal output
13+
const RED = "\x1b[31m";
14+
const YELLOW = "\x1b[33m";
15+
const RESET = "\x1b[0m";
16+
17+
function notifyEventLoopBlocked(timeMs: number, asyncType: string): void {
18+
if (env.EVENT_LOOP_MONITOR_NOTIFY_ENABLED !== "1") {
19+
return;
20+
}
21+
22+
console.warn(
23+
`${RED}⚠️ Event loop blocked${RESET} for ${YELLOW}${timeMs.toFixed(
24+
1
25+
)}ms${RESET} (${asyncType})`
26+
);
27+
}
28+
1229
const cache = new Map<number, { type: string; start?: [number, number]; parentCtx?: Context }>();
1330

1431
function init(asyncId: number, type: string, triggerAsyncId: number, resource: any) {
@@ -66,6 +83,8 @@ function after(asyncId: number) {
6683
);
6784

6885
newSpan.end();
86+
87+
notifyEventLoopBlocked(time, cached.type);
6988
}
7089
}
7190

0 commit comments

Comments
 (0)