File tree Expand file tree Collapse file tree 2 files changed +40
-0
lines changed Expand file tree Collapse file tree 2 files changed +40
-0
lines changed Original file line number Diff line number Diff line change @@ -186,3 +186,4 @@ export { apiRateLimiter } from "./services/apiRateLimit.server";
186
186
export { socketIo } from "./v3/handleSocketIo.server" ;
187
187
export { wss } from "./v3/handleWebsockets.server" ;
188
188
export { registryProxy } from "./v3/registryProxy.server" ;
189
+ export { eventLoopMonitor } from "./eventLoopMonitor.server" ;
Original file line number Diff line number Diff line change
1
+ import { createHook } from "node:async_hooks" ;
2
+ import { logger } from "./services/logger.server" ;
3
+ import { singleton } from "./utils/singleton" ;
4
+
5
+ const THRESHOLD_NS = 1e8 ; // 100ms
6
+
7
+ const cache = new Map < number , [ number , number ] > ( ) ;
8
+
9
+ function before ( asyncId : number ) {
10
+ cache . set ( asyncId , process . hrtime ( ) ) ;
11
+ }
12
+
13
+ function after ( asyncId : number ) {
14
+ const cached = cache . get ( asyncId ) ;
15
+ if ( cached == null ) {
16
+ return ;
17
+ }
18
+ cache . delete ( asyncId ) ;
19
+
20
+ const diff = process . hrtime ( cached ) ;
21
+ const diffNs = diff [ 0 ] * 1e9 + diff [ 1 ] ;
22
+ if ( diffNs > THRESHOLD_NS ) {
23
+ const time = diffNs / 1e6 ; // in ms
24
+
25
+ logger . error ( `Event loop was blocked for ${ time } ms` , {
26
+ label : "EventLoopMonitor" ,
27
+ startTime : new Date ( new Date ( ) . getTime ( ) - time ) ,
28
+ durationMs : time ,
29
+ } ) ;
30
+ }
31
+ }
32
+
33
+ export const eventLoopMonitor = singleton ( "eventLoopMonitor" , ( ) => {
34
+ console . log ( "🥸 Initializing event loop monitor" ) ;
35
+
36
+ const asyncHook = createHook ( { before, after } ) ;
37
+ asyncHook . enable ( ) ;
38
+ return asyncHook ;
39
+ } ) ;
You can’t perform that action at this time.
0 commit comments