Skip to content

Fix eager evaluation of fallback routing in resolveRouting#922

Open
zeckem19 wants to merge 3 commits intotrinodb:mainfrom
zeckem19:fix/orElseGet-eager-evaluation
Open

Fix eager evaluation of fallback routing in resolveRouting#922
zeckem19 wants to merge 3 commits intotrinodb:mainfrom
zeckem19:fix/orElseGet-eager-evaluation

Conversation

@zeckem19
Copy link

@zeckem19 zeckem19 commented Feb 16, 2026

Summary

  • Change Optional.orElse() to Optional.orElseGet() in RoutingTargetHandler.resolveRouting() to prevent eager evaluation of the fallback path

Problem

Optional.orElse(value) eagerly evaluates value , in resolveRouting(), this means getRoutingTargetResponse(request) is always called, even when the query ID is found in the cache and previousCluster is present.

For requests like GET /ui/query.html?queryId (e.g. Trino Web UI tracking links via Superset), the request has no routing headers (X-Trino-Routing-Group, etc.). When getRoutingTargetResponse() runs the routing rules and falls through to provideBackendConfiguration(), it throws IllegalStateException: Number of active backends found zero if no default backend is configured. This exception propagates before .orElse() can return the cached result, causing a 500 error even though the query ID was successfully resolved.

Fix

Replace .orElse(getRoutingTargetResponse(request)) with .orElseGet(() -> getRoutingTargetResponse(request)) so the fallback is only evaluated when previousCluster is empty.

Test plan

  • Added testResolveRoutingWithKnownQueryIdAndFailingFallback which verifies that when a query ID is found in the cache but the fallback routing would throw, resolveRouting still returns the cached backend successfully
  • The test fails with orElse() and passes with orElseGet()

Fixes #920

Change Optional.orElse() to Optional.orElseGet() in resolveRouting to
prevent eager evaluation of getRoutingTargetResponse(). With orElse(),
the fallback is always evaluated even when previousCluster is present.
If the fallback throws (e.g. no backends for the routing group), the
exception propagates before orElse() can return the cached result.

This causes 500 errors on /ui/query.html requests that have a known
query ID in the cache but no X-Trino-Routing-Group header, because
the routing rules cannot resolve a valid routing group for browser
requests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cla-bot
Copy link

cla-bot bot commented Feb 16, 2026

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

@zeckem19
Copy link
Author

@ebyhr i added the test, and have emailed the CLA (zeckem19)

@cla-bot
Copy link

cla-bot bot commented Feb 16, 2026

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

1 similar comment
@cla-bot
Copy link

cla-bot bot commented Feb 16, 2026

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

@ebyhr
Copy link
Member

ebyhr commented Feb 16, 2026

Please fix CI failure:

Error:  src/test/java/io/trino/gateway/ha/handler/TestRoutingTargetHandler.java:[310] (regexp) RegexpMultiline: Line has trailing whitespace

Also, please follow the PR template next time.

Removed reference to GitHub issue 920 in test case comments.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zeckem19 zeckem19 force-pushed the fix/orElseGet-eager-evaluation branch from 63f4c00 to 16a8750 Compare February 16, 2026 15:05
@cla-bot
Copy link

cla-bot bot commented Feb 16, 2026

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

@vaultah
Copy link
Contributor

vaultah commented Feb 16, 2026

Thanks for fixing this. Just two cents/impact statement:

In trino-gateway 16, QueryCountBasedRouter overrode provideBackendConfiguration and selected from its in-memory clusterStats via getBackendConfigurationForRoutingGroup.

In trino-gateway 17, QueryCountBasedRouter no longer overrides provideBackendConfiguration. The inherited BaseRoutingManager method always does a DB call.

Practically this means that when using QueryCountBasedRouter, due to the eager getRoutingTargetResponse evaluation, trino-gateway 17 performs one or two DB calls for every routing decision/request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

infoUri broken likely due to eager evaluation failure on /ui/query.html

3 participants

Comments