test: pool and reuse query compiler test workers (#5382)
Our tests were spending most of the time compiling the query compiler
(by V8), as well as loading it from disk repeatedly, initializing
Node.js runtime in each test worker etc.
This commit introduces a pool of test workers that are reused across
tests. The same worker is only used for one test at a time (concurrent
tests use different workers), and the worker is never reused after an
error occurs in it (many errors are recoverable but Rust panics aren't,
because WebAssembly doesn't support unwinding, so reusing the same
WebAssembly instance after a panic will lead to memory leaks at best and
undefined behaviour at worst; it's simpler to treat all errors as
unrecoverable and destroy the worker though).
This change makes the tests an order of magnitude faster, and makes them
complete in less than 90 seconds on my machine. The more tests we fix,
the faster they will become, because less new workers will be
initialized.
The speed gain with `cargo-nextest` is less dramatic because it uses
multiple isolated processes, which leads to many independent Node.js
child processes being started, each with their own worker pool, but it's
still 3.8x faster on my machine after this change, completing in less
than 4 minutes.