Repository navigation
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the APIs needed to embed goexec in Turbopack: entered runtime contexts, borrowed caller-thread
Handle::block_on, independently owned cancellation handles, worker lifecycle hooks, and shutdown that joins all workers and the monitor. ExistingRuntime::block_onand timeout shutdown remain available.Handle::block_onmarks only waits between polls as blocking and reacquires an execution permit before polling again. Nested waits work with one permit. Calls inside an already marked blocking region are rejected. Hook callbacks run outside scheduler locks; a hook panic closes admission and cancels tasks.Task publications notify registered event listeners without taking the scheduler mutex. Workers retain their stealing peer lists until the worker set grows, and retain permits across a bounded poll loop with scheduler checkpoints. Permit acquisition and FIFO priority for returning callers remain protected by the scheduler.
Blocking handoff measures the unchanged default 100µs grace period from call entry. One scan can replace multiple mature blocked workers when queued work needs them, reserving a replacement for every released permit and respecting the configured thread cap. This retains a clock read at the outermost blocking boundary. WASM uses the event's Future interface with the existing parker.
Cancellation registries reuse sharded Slab slots, with at least 16 shards even at parallelism 1 to separate external registration from completion. JoinHandle uses async-task's result storage directly; dropping it still detaches the task. User futures of up to 64 bytes share async-task's pinned allocation, while larger futures retain the previous
Pin<Box<Abortable<F>>>layout. Safe pin projection and pinned drop preserve address stability and isolate poll/destructor panics. Unobserved output destructor panics are also isolated. Per-worker poll counts use a single-writer atomic store.Verification
Performance
Final goexec SHA:
19171c705febb83495f98773c604594f488b04e6.Measured locally on Apple M3 Max (16 logical CPUs, 48 GiB), release/thin LTO/one codegen unit/TurboMalloc. Each comparison contains 12 workloads at parallelism 1/4/16, 10 alternating process pairs, then a separate 10-pair confirmation: 1,440 observations per comparison, 2,880 total. Profiling and exploratory builds are excluded. Binary hashes and identical fixtures were verified. Intervals are paired log-ratio t intervals (95%, 9 degrees of freedom), without multiplicity correction; series are not pooled. This is not a dedicated machine.
Against the immediately previous goexec
ddd0fcfb, the allocation/sharding/counter changes produced these replicated confirmation results:No product build/dev/HMR improvement replicated in this final follow-up. Parallelism-1 HMR increased 9.4% in confirmation (4.7% to 14.3%), but the primary series was inconclusive (-0.2%, -7.4% to 7.4%); this is not evidence of equivalence.
A fresh comparison against Tokio-based Next.js
22fffea9d4found the following replicated product results. These include the entire migration: Tokio, PriorityRunner and inline-read execution removal, plus I/O/process/HTTP/N-API changes. They do not isolate goexec.Small-app, warm build and HMR had no replicated clear timing change. The heavy fixture currently enables Lodash only. Parallelism-16 cold-build peak RSS medians increased from 1563.2 to 1669.2 MiB; sampled peak process-tree thread medians increased from 162 to 188. Sampling requests 10ms intervals and can miss brief peaks or double-count shared pages.
Executor-only spawn/join beats Tokio at parallelism 1 (-10.9%) but remains slower at 4/16 (+11.1%/+22.4%). Yield is faster at all three parallelisms, with Tokio's existing Turbopack LIFO-disabled setting. Blocking 1ms batches remain slower (+827.0%/+267.1%/+72.8%): Tokio immediately delegates to its blocking pool, while goexec keeps its 100µs handoff grace period. At parallelism 1 the sampled peak thread median is 130 for Tokio versus 13 for goexec. These results do not establish general Tokio performance parity.