← All context files

lite/node-dev-runtime.md

lite – The Node Dev Runtime (execute() is really synchronous)

execute() is synchronous by design — that is the whole point, since one codebase runs under both Classic ASP and Node. ASP is genuinely synchronous because ADODB blocks the OS thread. Node had to be made to match.

What changed in 6.9.0

Before 6.9.0, the Node path used deasync.loopWhile(), which re-enters and pumps the Node event loop until the query resolves. So while it "blocked", other callbacks fired and exceptions propagated through a loop that shouldn't have been running. The symptom was a hard crash:

FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal

— the dev API process dying outright, typically under a cold API plus concurrent traffic plus an erroring request. Every crash of that class was "a callback fired during the block."

From 6.9.0, deasync is gone. execute() now:

  1. posts the SQL to a worker thread that owns its own mssql pool;
  2. calls Atomics.wait() on a SharedArrayBuffer — a real OS-level block, during which the event loop does not run and no callback can fire;
  3. wakes on the worker's Atomics.notify();
  4. pulls the result via receiveMessageOnPort(), which drains a MessagePort without the event loop (you cannot use postMessage/.on('message') for the return path — the main thread is blocked).

A real block admits no callbacks, so the crash class disappears. Route code (validate / secure / preprocess) stays synchronous and untouched, and the ASP/ADODB path is unchanged, so production is unaffected either way.

What this means for you day to day

Things not to retry

Measurement trap

git-bash on Windows spawns processes in ~725ms, so a for … do curl … done loop measures the shell, not the API — easily good for a phantom 20× regression. Use a single curl --parallel process, or curl's own time_total.

Deploying a lite change into a project

lite is Rollup-inlined by goldfish. Copying dist into a project's node_modules/@kyd/lite does nothing on its own — the project must be rebuilt afterwards for the change to reach the bundle.

Related: a package's version label can lie if node_modules was overwritten in place during a spike (manifest says one version, code is another). Check that before trusting a .node-build diff.