Repository navigation
Description
Summary
The connection workflow is red on main on its very first run. The workflow was introduced by the #52 merge (08ffdb2b, "feat(l2): pluggable Connection — chdb/connection for @clickhouse/client"), so connection.yml ran for the first time on push to main and the parity job failed.
- Failing run: https://github.com/chdb-io/chdb-node/actions/runs/28079477030
- Triggering commit:
08ffdb2b(merge of feat(l2): pluggable Connection — chdb/connection for @clickhouse/client #52, by @ShawnChen-Sirius) - Jobs:
contract✅ (in-repo Connection contract suite),parity❌ (cross-suite against upstream@clickhouse/client)
Failure signature
parity clones ClickHouse/clickhouse-js@main, injects ChdbConnection, applies skip_list.json, and runs the upstream Node integration suite. Result:
Test Files 27 passed | 2 skipped (29)
Errors 1 error
All test files pass, but vitest reports 1 unhandled error, which makes the job exit non-zero:
⎯⎯ Unhandled Errors ⎯⎯
Vitest caught 1 unhandled error during the test run.
⎯⎯ Uncaught Exception ⎯⎯
Error: ResultSet has been closed
❯ ResultSet.close packages/client-node/dist/result_set.js:244:30
❯ packages/client-node/__tests__/integration/node_select_streaming.test.ts:91:16
This error originated in "packages/client-node/__tests__/integration/node_select_streaming.test.ts".
The latest test that might've caused the error is "can pause response stream".
Signature: connection/parity → node_select_streaming.test.ts "can pause response stream" → unhandled Error: ResultSet has been closed (ResultSet.close, upstream result_set.js:244).
Root-cause hypothesis
The upstream "can pause response stream" test streams 10k rows and calls stream.pause() / stream.resume() every 1000 rows, then lets the async iterator drain to completion:
const stream = result.stream();
for await (const rows of stream) {
rows.forEach((row) => {
if (++i % 1000 === 0) { stream.pause(); setTimeout(() => stream.resume(), 100); }
});
}With ChdbConnection injected, the underlying chdb stream/result appears to be closed early (on stream end and/or on pause), so the subsequent ResultSet.close() — invoked by the upstream stream-lifecycle teardown — hits an already-closed result and throws ResultSet has been closed. Because the throw happens in an async end/close handler rather than an awaited path, it surfaces as an unhandled error and fails the run, even though the test's own assertions passed.
In short: the new pluggable-connection streaming path (src/connection/chdb-connection.ts) does not make close() idempotent across the pause/resume + drain lifecycle, so a double-close escapes.
Reproduction
CI: re-run the connection workflow on main @ 08ffdb2b (the parity job).
Local (Linux x86_64, mirrors the runner):
git checkout 08ffdb2b
npm install --ignore-scripts && npm run libchdb && npm run build
node tests/clickhouse-js/runner.mjs
# watch packages/client-node/__tests__/integration/node_select_streaming.test.ts
# → "can pause response stream" → unhandled "Error: ResultSet has been closed"Suggested directions (one of)
- Make the adapter's result/stream
close()idempotent — a second close (or a close after the stream has already ended) should be a no-op, not a throw. This is the most likely correct fix and matches the upstream contract. - Don't eagerly close the underlying result on stream end / pause in
ChdbConnection; defer teardown to the explicitclose()so upstream owns the lifecycle. - If pause/resume on a chdb-backed stream is a genuine capability gap, add
node_select_streaming.test.ts "can pause response stream"totests/clickhouse-js/skip_list.json— the workflow header explicitly documents this as the alternative when a parity failure is a real chdb gap rather than an adapter bug.
Dedup
No open or closed chdb-node issue matches this signature (searched ResultSet has been closed, parity, connection workflow). Distinct from #53 (macOS-arm64/Node-20 async-stress 120s hang from #51 — different workflow, OS, and root cause).
Filed automatically by chibugai's CI monitor (Responsibility 1: failure on main). cc @ShawnChen-Sirius @auxten @wudidapaopao
Activity
fix(ci): stop close()-mid-flight engine abort (#53) and absorb Result…
Merge pull request #56 from ShawnChen-Sirius/fix/ci-issues-53-54