@@ -106,6 +106,17 @@ function wrapAllMethods(
106106 return ( ) => restores . forEach ( r => r ( ) ) ;
107107}
108108
109+ /** Detect queue-like objects whose `get`/`put`/`process` are worker-loop
110+ * infrastructure, not application operations. Their blocking `get()` can
111+ * span seconds of idle time and pollute the profile. */
112+ function isQueueLike ( obj : any ) : boolean {
113+ try {
114+ return typeof obj . get === 'function' && typeof obj . put === 'function' ;
115+ } catch {
116+ return false ;
117+ }
118+ }
119+
109120// ─── Profiler ────────────────────────────────────────────────────────────────
110121
111122class Profiler {
@@ -254,23 +265,41 @@ class Profiler {
254265 if ( pxe . simulator ) wrapped . add ( pxe . simulator ) ;
255266 this . _cleanups . push ( installSimulatorInterceptorFromPXE ( pxe , this ) ) ;
256267
257- this . instrumentPxeInternals ( pxe , wrapped ) ;
268+ this . instrumentInternals ( pxe , wrapped , 3 ) ;
258269 }
259270 }
260271
261- /** Walk PXE properties and wrap methods on internal services/stores. */
262- private instrumentPxeInternals ( pxe : any , alreadyWrapped : Set < any > ) {
263- for ( const key of Object . getOwnPropertyNames ( pxe ) ) {
272+ /**
273+ * Walk an object's properties and wrap methods on sub-objects.
274+ * Recurses up to `depth` levels (default 2) to catch nested objects
275+ * like `jobCoordinator.kvStore` whose `transactionAsync` needs its
276+ * callback arg zone-bound for proper context propagation.
277+ *
278+ * Queue-like objects (BaseMemoryQueue, FifoQueue, etc.) are skipped:
279+ * their `get`/`put`/`process` methods are worker-loop infrastructure
280+ * that blocks for seconds waiting for items, not application operations.
281+ */
282+ private instrumentInternals ( root : any , alreadyWrapped : Set < any > , depth = 2 ) {
283+ if ( depth <= 0 ) return ;
284+ for ( const key of Object . getOwnPropertyNames ( root ) ) {
264285 if ( key . startsWith ( '_' ) || key === 'log' ) continue ;
265286 let value : any ;
266- try { value = pxe [ key ] ; } catch { continue ; }
287+ try { value = root [ key ] ; } catch { continue ; }
267288 if ( ! value || typeof value !== 'object' || alreadyWrapped . has ( value ) ) continue ;
268289
269290 const methods = collectMethods ( value ) ;
270291 if ( methods . length === 0 ) continue ;
271292
293+ // Skip queue-like objects — they have `get`+`put` (or `process`)
294+ // and their blocking `get()` can span seconds of idle time.
295+ if ( isQueueLike ( value ) ) {
296+ alreadyWrapped . add ( value ) ;
297+ continue ;
298+ }
299+
272300 alreadyWrapped . add ( value ) ;
273301 this . _cleanups . push ( wrapAllMethods ( value , 'store' , this ) ) ;
302+ this . instrumentInternals ( value , alreadyWrapped , depth - 1 ) ;
274303 }
275304 }
276305
0 commit comments