v9: Major rework - #18
Merged
Merged
Conversation
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
… result codes Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…nsaction and prepare-failure fixes Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…ull query, 20x Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…s little Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…pool Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…r and packaging tests Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…s left running Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…ainer test matrix Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…n Windows in CI Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
… on every check Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
Node availability was checked per target before adding combinations:
- setup-node delivers 26 on every hosted runner (linux/darwin/win,
x64 and arm64), so the fast `test` job now runs os x node with
{24, 26} and gains ubuntu-22.04-arm (arm64 Linux was previously
suite-tested only inside the slower `build` matrix).
- alpine3.20 — the musl build variant — has no Node 26 image
(node:26-alpine tags start at 3.22), so build-qemu stays on 24 and
the Node-major musl coverage comes from a consumer: the new
prebuild-consumer-musl job runs the suite against the
alpine3.20-built artifact inside node:26-alpine3.22.
- prebuild-consumer (glibc/darwin/win, node 26) downloads the build
artifacts and runs the suite with PREBUILDS_ONLY=1 — no compile, so
green means the shipped binary itself passed, proving the napi
one-build-many-Nodes promise the package is sold on.
- Electron is unaffected: 43.4.1 embeds Node 24.18.1 (measured), so
those jobs add a different runtime, not a different Node major.
Deliberately not added: node 26 on windows-11-arm and macos-15-intel
(slow runners, napi-identical to covered pairs), musl arm64 x 26
(arch covered by build-qemu), and any change to the musl build floor
(alpine3.20 went EOL 2026-04-01 — bumping the floor is its own
decision). publish gates on both new jobs.
Verified locally: full suite in node:26-alpine3.22 against a musl
prebuild built in-container (750/748/0/2, same as darwin/node 26);
PREBUILDS_ONLY=1 suite green on this machine; actionlint reports no
new findings.
…pins
test (windows-latest, node=26) failed at link: LNK1117 syntax error in
option 'opt:lldltojobs=2', with -flto=thin D9002/LNK4044 warnings on
every project. Chain: node-gyp builds build/config.gypi from the
RUNNING node's process.config (not the headers' config.gypi — that is
only read with --nodedir/--dist-url); the official Windows Node 26
builds are clang-cl/ThinLTO, so process.config carries
enable_thin_lto="true" and lto_jobs="2"; Node 26's common.gypi (new
since 24) turns those into -flto=thin and /opt:lldltojobs=2
AdditionalOptions on Windows; MSVC link.exe is not lld-link and the
latter is a hard LNK1117. Linux/macOS and Node 24 are unaffected
(headers config and official 24 builds say false), which is exactly
the observed matrix.
Fixed upstream in node-gyp 13.0.0 ("disable LTO for addon builds on
Windows", nodejs/node-gyp#3331; 13.0.1 adds a VS2026 fix), so the pin
moves 12.x -> 13.x and resolves to 13.0.1 — 13.0.2 is 23h old and
inside the pnpm minimumReleaseAge gate. The only 13.0.0 breaking
change is the node engine range ^22.22.2 || ^24.15.0 || >=26, above
our >=24 floor in practice.
The three prebuild-consumer failures were transient: all died at
"Set up job" with "Unable to resolve action actions/checkout@<sha>"
before any step, while the same SHA resolved in every other job of
the same run — a GitHub action-resolution blip, not a workflow bug.
All 24 action pins refreshed with gh actlock -u (SHAs spot-verified
against the git refs API): checkout v7.0.1, setup-node v7.0.0,
setup-python v7.0.0, upload-artifact v7.0.1; the rest were already
latest.
Verified locally through node-gyp 13.0.1: full rebuild + suite
(750/748/0/2), and the prebuildify -> PREBUILDS_ONLY=1 path the build
matrix uses (750/748/0). Windows itself can only be proven in CI.
On the ubuntu-22.04-arm build job (run 33074153055), 'round-trips function' failed with "database is busy: sync methods require a fully idle database" instead of the expected bind TypeError — once, in the first integer mode, with the same test green 100ms later in the next mode. Mechanism, reproduced deterministically on the local prebuild: a bind-rejected value throws synchronously out of the db-level wrappers (established v9 semantics), and that throw skips their trailing finalize — the call's async prepare is abandoned in flight, so db.pending stays elevated past the point where the driver's await resolved. Instrumenting the exact 15-path sequence showed +1 pending accumulated per rejected db-level path (5 after db.run). On a fast machine the four awaited stmt paths that follow always drain the stragglers before db.getSync; on a slow, preempted runner one can still be in flight, and the first sync path meets a busy gate. The async paths cannot promise idleness at await-resolution (their internal prepare/finalize round trips are deliberately not part of the awaited op), so the sync drivers in test/support/bindpaths.js now await db.wait() first — an exclusive call that runs only at pending == 0, the same drain discipline the stmt drivers already apply by resolving from inside stmt.finalize's callback. No assertion changed: the sync paths must still produce the bind TypeError. Evidence: PREBUILDS_ONLY node repro shows pending=1 after a sync-throwing db.get, getSync busy, then wait -> 0 -> getSync OK; marshalling 20/20 clean; full suite 750/748/0/2.
…eate electron (ubuntu-latest) on run 33078211871 failed its whole backup suite: the describe's before-hook threw EEXIST on mkdir 'test/tmp', cancelling all 14 tests. node --test runs each file in its own process, and test/support/helper.js's ensureExists did existsSync-then-mkdirSync — two before-hooks creating test/tmp in the same instant race the check, and the loser gets EEXIST. Electron child processes start slower than plain Node's, which widened the window enough to hit it; the same latent race existed for every plain-Node run. mkdirSync(recursive) has mkdir -p semantics: race-free, and an existing directory is fine. Proven with a 6-process concurrent probe on a fresh directory, 40 rounds: the old form threw EEXIST in 40/40 rounds, recursive in 0/40. Every other mkdir in test/ and tools/ already used recursive; this was the only holdout. No assertion changed. Verified: backup.test.js 14/14, full suite 750/748/0/2, lint clean.
…sion load Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…g SQLCipher build path Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…w builder Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
…er field Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
The SQLCipher section was renamed at some point but two links still
pointed at #building-for-sqlcipher -- one in the README, one in
docs/install.md. Both are now the real anchor. A link/anchor sweep over
README, MIGRATING-TO-V9, SECURITY and docs/ finds no others, and 33 of
the 35 documented JS snippets parse clean (the other two are deliberate
fragments: a "{ ... }" elision and an anonymous generated function).
docs/performance.md gains "Against a C-extension driver in another
language". Everything there so far compares Node against Node; this adds
an outside check against CPython's apsw over a real 13 GB store, which
is worth recording because it isolates the mechanism rather than just a
ratio. Widening the projection over one fixed plan shows count(*) at
1.02x -- parity, so execution, binding and call overhead are not the
gap -- with the whole difference appearing only once rows are built:
+50 ns per row, +6.5 ns per value. The per-row half is a boundary
crossing, not object construction (calling the generated builder from JS
costs ~7 ns/row), because CPython lets an extension fill a tuple in C
while Node-API has no bulk constructor. Two consequences for callers:
projecting fewer columns is the lever that works, and row mode is not
one -- rowMode: 'array' moves nothing, which the existing "How rows are
built" section already predicted.
That measurement did not come from pnpm run bench, so the file's opening
claim that nothing is hand-timed is now qualified, and the caveats
(warm-cache-only, a 3.53.3-vs-3.53.4 SQLite mismatch, private dataset,
one machine) are listed under Limits of these numbers.
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.
No description provided.