You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
FEATURE: add Context#call_async and Context#eval_async
These work like call and eval, except that when the result is a promise they block until it settles and return the settled value. A rejected promise raises MiniRacer::RuntimeError, like a synchronous throw, and non-promise results are returned as-is.
While waiting, the V8 thread alternates between draining the microtask queue and pumping the platform message loop in wait-for-work mode, so there is no polling: microtask chains settle immediately, and delayed or background work (Atomics.waitAsync timers, async wasm compilation) wakes the loop when its tasks are posted.
TerminateExecution doesn't wake a parked message loop, and when called while no JS is running it only queues a termination for the next JS entry. v8_terminate_execution therefore also sets a flag on the State and posts a no-op wakeup task, so the timeout watchdog, Context#stop and Ruby thread interrupts can all end a pending await. A promise that can never settle blocks like an infinite loop until one of those stops it.
The new methods use two new request opcodes ('D' and 'F') sharing the existing v8_call/v8_eval implementations. Ruby callbacks invoked while waiting go through the usual nested-dispatch path, and exceptions they raise propagate out through the promise rejection. TruffleRuby raises MiniRacer::Error.
Copy file name to clipboardExpand all lines: CHANGELOG
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,5 @@
1
1
- Unreleased
2
+
- Add `Context#call_async` and `Context#eval_async`: like `call`/`eval` but block until a returned Promise settles and return the settled value; rejections raise `MiniRacer::RuntimeError`
2
3
- Fix a race introduced in 0.21.4 where a request sent right after a nested dispatch (e.g. `perform_microtask_checkpoint` or a nested `call` from an attached callback) could be dropped, deadlocking the context
Non-Promise results pass through unchanged, so `call_async` is a drop-in
372
+
superset of `call` (same for `eval_async`/`eval`).
373
+
374
+
A promise that never settles blocks forever, just like an infinite loop. The
375
+
`timeout:` option and `Context#stop` both interrupt it, raising
376
+
`MiniRacer::ScriptTerminatedError`.
377
+
351
378
### Microtask checkpoints
352
379
353
380
V8 drains its microtask queue (e.g. callbacks queued via `Promise.resolve().then(...)`) automatically when script execution returns to the embedder, so most code "just works":
0 commit comments