Skip to content

feat: support Symbol.asyncDispose on client, session, and operation - #586

Open
vuanhphung wants to merge 3 commits into
mainfrom
feat/issue-331-async-dispose
Open

vuanhphung wants to merge 3 commits into
mainfrom
feat/issue-331-async-dispose

Conversation

@vuanhphung

@vuanhphung vuanhphung commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator

DBSQLClient, DBSQLSession, and DBSQLOperation now implement [Symbol.asyncDispose](), so they work with await using (TC39 explicit resource management). Disposal delegates to close(): disposing an already-closed object is a no-op, and a real close failure still surfaces. The method is on the shared facades, so it covers both the Thrift and kernel backends. It's also declared on IDBSQLClient, IDBSQLSession, and IOperation, because those are the types connect(), openSession(), and executeStatement() return. Custom implementations of those interfaces will need to add the method; the CHANGELOG says so.

Typings: the emitted .d.ts reference Symbol.asyncDispose. TypeScript only declares it with the esnext.disposable lib, and @types/node 18.11 and 20.3.0 don't declare it either. 20.3.0 is the version consumers get transitively through apache-arrow. So the package ships the same SymbolConstructor.asyncDispose: unique symbol declaration that TypeScript and @types/node use, and the declarations merge cleanly. At runtime the symbol exists on every supported Node line. Node 24+ runs await using natively; Node 22 needs TypeScript 5.2+ to compile it.

Verification:

  • Unit tests cover dispose, the already-closed no-op, and close-error propagation on the Thrift and kernel facades. npm test, lint, prettier, type-check, and build all pass.
  • Consumer type-compat matrix: consumer projects built from npm pack tarballs of main and of this branch. It covers 1,232 configs: TypeScript 4.7–7.0 × @types/node (transitive, 18.11, 20.3.0, 20.19, 22, 24, 26) × lib (default/es2022/esnext/esnext.disposable) × skipLibCheck on/off × node10/node16. Each config runs with and without the @types/thrift/node-int64/node-fetch typings that skipLibCheck: false needs. No config gets new errors. All 681 configs that are clean on main stay clean, including 89 with skipLibCheck: false (TS 4.7–7.0, with @types/node 18.11 and 20.3.0 among them). Explicit [Symbol.asyncDispose]() calls type-check in all of those configs. await using type-checks in every eligible config (TS ≥ 5.2 with a disposable lib): 105 with skipLibCheck and 25 without.
  • Live warehouse: await using closes the operation, then the session, then the client on both backends. Tested on Node 24 (native and TS-downleveled) and Node 22.23.4 (downleveled). An error thrown inside the block propagates, and disposal still runs. Related e2e specs pass.
  • No performance impact. This only adds methods that run on dispose; no request, fetch, or result path changes, and the new declaration module is type-only (it is never loaded at runtime).

Fixes #331

This pull request and its description were written by Isaac.

DBSQLClient, DBSQLSession, and DBSQLOperation (and the IDBSQLClient,
IDBSQLSession, and IOperation interfaces) gain [Symbol.asyncDispose](),
which delegates to close(), so `await using` works on both backends.
Disposing an already-closed object is a no-op.

The published typings declare SymbolConstructor.asyncDispose themselves,
so consumers don't need TypeScript's esnext.disposable lib or a recent
@types/node.

Fixes #331

Signed-off-by: Vu Anh Phung <vu.phung@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No issues identified by the review bot.

@vuanhphung

Copy link
Copy Markdown
Collaborator Author

@bot Please mention adding esnext.disposable to compilerOptions.lib when the consumer’s typings don’t already provide disposable declarations. Otherwise, the documented example can fail even with TypeScript 5.2+.

@github-actions

Copy link
Copy Markdown

Thanks for your contribution! To satisfy the DCO policy in our contributing guide every commit message must include a sign-off message. One or more of your commits is missing this message. You can reword previous commit messages with an interactive rebase (git rebase -i main).

Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>
@peco-engineer-bot

Copy link
Copy Markdown
Contributor

Pushed ec3a551 to feat/issue-331-async-dispose addressing your request.

Started from 82b6e7b. I added a note to the README's "Automatic cleanup with await using" section. It says TypeScript needs the disposable declarations, such as the global AsyncDisposable type, to compile await using. If the consumer's typings don't already provide them, they should add "esnext.disposable" (or "esnext") to compilerOptions.lib in tsconfig.json. Otherwise the example can fail to compile even with TypeScript 5.2+. Only the README changed. npm run prettier passes. I didn't run the build or tests because no code changed.

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No issues identified by the review bot.

@github-actions

Copy link
Copy Markdown

Thanks for your contribution! To satisfy the DCO policy in our contributing guide every commit message must include a sign-off message. One or more of your commits is missing this message. You can reword previous commit messages with an interactive rebase (git rebase -i main).

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No issues identified by the review bot.

This branch was successfully deployed

1 active deployment
azure-prod — ec3a551b Deployed Nov 12, 2026 by peco-engineer-bot[bot] via e2e-test (22.23.4, 22_23_4) #1941
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Request for enhancement: Support Symbol.asyncDispose for session and operation

1 participant