Skip to content

fix: build the host list provider from a verified database dialect - #1292

Open
karenc-bq wants to merge 1 commit into
mainfrom
fix/host-list-provider-initialization
Open

karenc-bq wants to merge 1 commit into
mainfrom
fix/host-list-provider-initialization

Conversation

@karenc-bq

@karenc-bq karenc-bq commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Description

The async host list provider was built before any connection existed, picked by checking the configured plugins against a hardcoded list of those that require topology. That list has to be updated whenever such a plugin is added. Moreover, instead of checking against the plugins, the provider should be determined by the database dialect that knows the cluster's topology shape.

This PR updates the async path to determine the correct host list provider using methods from the database dialects, matching the sync driver behaviour.

  1. Provider selection moved onto the dialect. _build_host_list_provider in aio/wrapper.py decided the provider from a hardcoded _TOPOLOGY_REQUIRING_PLUGINS frozenset, then substring-matched "MultiAz" and "GlobalAurora" against the dialect's class name and scraped private query constants off it with getattr(..., None), falling back to the Aurora provider whenever a lookup came back empty. A dialect not matching those substrings silently got the wrong topology SQL. The dialect now supplies its own provider via get_async_host_list_provider_supplier().

  2. Async verification skipped PostgreSQL and could only make one hop. update_database_dialect returned early and marked the dialect settled for any driver other than aiomysql, and for MySQL hardcoded a single AuroraMysqlDialect check rather than reading dialect_update_candidates. PostgreSQL kept its pattern guess for the life of the connection, and chained upgrades such as Aurora MySQL to Global Aurora MySQL were unreachable. Verification now runs through query_for_dialect_async, which walks the chain for both engines.

  3. Dialect identification is rule data, not ten hand-written bodies. is_dialect could not be reused by the async path: def is_dialect cannot be overridden by async def, and the sync probe runs through a thread pool that cannot accept an async connection. New dialect_verifier.py holds each dialect's queries and row predicates as data, with a sync and an async runner over them.

  4. A candidate that could not be asked was treated as fatal. On Aurora the Multi-AZ rule always errors, because rds_tools and the topology table are absent there, so verification raised instead of trying the next candidate and left every Aurora cluster endpoint unconfirmed with its topology queries deferred. An erroring candidate is now skipped, the same answer as one returning no rows. The skip is silent, so a candidate failing for an unexpected reason leaves no trace.

  5. Topology queries now wait for a confirmed dialect, in both engines. PluginService gains is_dialect_confirmed, and RdsHostListProvider reports the hosts parsed from the connection properties until it is set, so no provider builds a topology monitor around a guessed dialect's SQL.

  6. Two async defects from the trailing slash on HostInfo.url. url is as_alias() plus a slash, so availability marks written keyed by alias and read keyed by url never matched and every mark was dropped; keys are now normalised, and the live HostInfo is marked too because host selection reads the object directly. The connection tracker also parsed the port out of a url, so int("3306/") raised and the port fell back to 5432, leaving a demoted MySQL writer's connections un-invalidated.

  7. Four log calls named message keys that do not exist. A missing key raises, and the logger falls back to the raw key only when no format arguments are passed. FailoverV2Plugin._invalid_invocation_on_closed_connection evaluated Messages.get as a call argument, so it raised that error in place of the FailoverSuccessError it was about to raise, and a caller touching a connection failover had closed got an unrelated exception instead of the failover signal. Live since 0b1ba85 (feat: failover v2 plugin (#1079), 2026-01-27); the other three raise only with debug logging on.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@karenc-bq
karenc-bq force-pushed the fix/host-list-provider-initialization branch from 6d70ebe to 69c14e6 Compare October 14, 2026 15:58

This branch has not been deployed

No deployments
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.

1 participant