Skip to content

Commit f694973

Browse files
committed
fix: polling event loop for ESM, 1s _waitForActiveHandles interval. PI main() progresses but slow.
1 parent 7895c77 commit f694973

2 files changed

Lines changed: 41 additions & 18 deletions

File tree

native/v8-runtime/src/session.rs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -879,23 +879,46 @@ pub(crate) fn run_event_loop(
879879
break;
880880
}
881881

882-
// Receive next command, with optional abort monitoring
883-
let cmd = if let Some(abort) = abort_rx {
884-
crossbeam_channel::select! {
885-
recv(rx) -> result => match result {
886-
Ok(cmd) => cmd,
887-
Err(_) => return EventLoopStatus::Terminated,
888-
},
889-
recv(abort) -> _ => {
890-
// Timeout fired — abort channel closed
891-
scope.terminate_execution();
892-
return EventLoopStatus::Terminated;
893-
},
882+
// Receive next command with interleaved microtask processing.
883+
// Instead of blocking indefinitely, use a short timeout so we can
884+
// periodically flush microtasks (like Node.js's libuv + DrainTasks pattern).
885+
let cmd = loop {
886+
let recv_result = if let Some(abort) = abort_rx {
887+
crossbeam_channel::select! {
888+
recv(rx) -> result => result.ok(),
889+
recv(abort) -> _ => {
890+
scope.terminate_execution();
891+
return EventLoopStatus::Terminated;
892+
},
893+
default(std::time::Duration::from_millis(1)) => None,
894+
}
895+
} else {
896+
rx.recv_timeout(std::time::Duration::from_millis(1)).ok()
897+
};
898+
if let Some(cmd) = recv_result {
899+
break cmd;
894900
}
895-
} else {
896-
match rx.recv() {
897-
Ok(cmd) => cmd,
898-
Err(_) => return EventLoopStatus::Terminated,
901+
// No command received — flush microtasks and check deferred queue
902+
scope.perform_microtask_checkpoint();
903+
if let Some(dq) = deferred {
904+
if !dq.lock().unwrap().is_empty() {
905+
// New deferred work appeared — drain it in the outer loop
906+
let frames: Vec<BinaryFrame> = dq.lock().unwrap().drain(..).collect();
907+
for frame in frames {
908+
let status = dispatch_event_loop_frame(scope, frame, pending);
909+
if !matches!(status, EventLoopStatus::Completed) {
910+
return status;
911+
}
912+
}
913+
}
914+
}
915+
// Check if we should exit
916+
if pending.len() == 0
917+
&& !execution::pending_module_evaluation_needs_wait(scope)
918+
&& !execution::pending_script_evaluation_needs_wait(scope)
919+
&& deferred.map(|dq| dq.lock().unwrap().is_empty()).unwrap_or(true)
920+
{
921+
return EventLoopStatus::Completed;
899922
}
900923
};
901924

packages/nodejs/src/bridge/active-handles.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ export function _waitForActiveHandles(): Promise<void> {
118118
complete();
119119
return;
120120
}
121-
setTimeout(poll, 100);
121+
setTimeout(poll, 1000);
122122
};
123-
setTimeout(poll, 100);
123+
setTimeout(poll, 1000);
124124
}),
125125
);
126126
}

0 commit comments

Comments
 (0)