Skip to content

fix(csharp): prevent infinite polling in SEA metadata queries#347

Open
msrathore-db wants to merge 2 commits intomainfrom
fix/sea-metadata-infinite-polling-timeout
Open

fix(csharp): prevent infinite polling in SEA metadata queries#347
msrathore-db wants to merge 2 commits intomainfrom
fix/sea-metadata-infinite-polling-timeout

Conversation

@msrathore-db
Copy link
Collaborator

Summary

  • Bug: ExecuteMetadataSqlAsync creates internal statements with _queryTimeoutSeconds=0 (no timeout). When called via ExecuteQuery() on a metadata statement (e.g. GetTables, GetColumns, GetCatalogs), CancellationToken.None is passed through, causing PollUntilCompleteAsync's while(true) loop to run indefinitely if the server query doesn't complete within the initial 10s REST API wait.
  • Impact: PowerBI users see frozen UI / infinite spinners when browsing tables or columns via the SEA (REST) protocol, with no way to cancel. The only escape is killing the process.
  • Fix: Wrap all metadata SQL execution with CreateMetadataTimeoutCts() (using _waitTimeoutSeconds, default 10s), matching the pattern already used by GetObjects(). Links caller-provided tokens so either the caller or the metadata timeout can terminate the operation.
  • Why Thrift is unaffected: Thrift uses native TGetTablesReq RPC — a single request-response call with no SQL or polling.

Root cause details

The code path: ExecuteQuery()ExecuteQueryAsync(CancellationToken.None)ExecuteMetadataCommandAsyncGetTablesAsync(CancellationToken.None)ExecuteMetadataSqlAsync(sql, CancellationToken.None) → creates new StatementExecutionStatement with _queryTimeoutSeconds=0PollWithTimeoutAsync sees <= 0PollUntilCompleteAsync(statementId, CancellationToken.None) → infinite while(true).

All SEA metadata commands are affected: GetCatalogs, GetSchemas, GetTables, GetColumns, GetColumnsExtended, GetPrimaryKeys, GetCrossReference, and GetCurrentCatalog() (SELECT CURRENT_CATALOG()).

Test plan

  • All 631 unit tests pass
  • All 18 SEA metadata E2E tests pass (SeaMetadataE2ETests)
  • Manual PowerBI validation with SEA protocol against slow/cold warehouse

This pull request was AI-assisted by Isaac.

…nt infinite polling

ExecuteMetadataSqlAsync creates internal statements with _queryTimeoutSeconds=0
(no timeout). When called via ExecuteQuery() on a metadata statement (e.g.
GetTables, GetColumns), CancellationToken.None is passed through, causing
PollUntilCompleteAsync's while(true) loop to run indefinitely if the server
query doesn't complete within the initial 10s wait.

This impacts PowerBI users who see frozen UI / infinite spinners when browsing
tables or columns via the SEA (REST) protocol, with no way to cancel.

Fix: wrap all metadata SQL execution with CreateMetadataTimeoutCts(), matching
the pattern already used by GetObjects(). Links caller-provided tokens so
either the caller or the metadata timeout can terminate the operation.

Co-authored-by: Isaac
// ExecuteMetadataCommandAsync → GetTablesAsync via ExecuteQuery()), the
// inner statement would have _queryTimeoutSeconds=0 and poll forever.
// Link the caller's token with a metadata timeout as a safety net.
using var metadataTimeoutCts = CreateMetadataTimeoutCts();
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems we have same bug for Thrift, can we fix that too?

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.

2 participants