Skip to content

fix: open each dataset once per request - #171

Merged
maxrjones merged 12 commits into
mainfrom
fix/single-open-per-request
Oct 8, 2026
Merged

maxrjones merged 12 commits into
mainfrom
fix/single-open-per-request

Conversation

@maxrjones

Copy link
Copy Markdown
Member

This PR keeps readers open for the duration of the backend, to be shared for both validation and rio-tiler's calls. It also makes it so URLs provided multiple times to the mosaic route share one reader.

This is motivated by poor performance observed in the AIR4US portal, which Slesa tracked to multiple openings of the same dataset. This is expensive in high-latency environment, especially for Icechunk stores where opening is a more expensive operation.

Separately, we could explore sharing open datasets across requests, but that requires a more comprehensive solution.

Testing

  • A new test fixture that monitors duplicate openings of a dataset.

PR checks

  • Standard CI runs automatically on each push.
  • To run the CDK synth check, add the run-cdk-checks label to this PR.
  • If you push more commits after that run completes, remove and re-add the label to run it again.
  • To trigger a dev deployment, add the deploy-dev label. It smoke-tests tiles from the native MUR, virtual MUR, and virtual NLDAS Icechunk stores after deployment.

maxrjones and others added 3 commits October 2, 2026 15:46
XarrayMosaicBackend opened every source to validate mosaic
compatibility, closed it, and rio-tiler's tile/part/point paths then
opened it again. For a large Icechunk store each open costs ~1.5s,
which doubled tile and point latency.

Keep the validation readers open for the life of the backend, route
rio-tiler's per-asset reader calls to them, and close them when the
request's backend context exits (or when validation fails part-way).
Duplicate URLs now share one reader.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
/info?show_times=true opened the dataset a second time to read its
time coordinate; read it from the reader the mosaic backend already
holds open.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added the fix label Oct 2, 2026
@maxrjones
maxrjones requested a review from hrodmn October 5, 2026 13:33
@maxrjones maxrjones self-assigned this Oct 5, 2026
@maxrjones
maxrjones requested a review from chuckwondo October 6, 2026 14:12
maxrjones and others added 2 commits October 7, 2026 16:34
The opens fixture patched guess_opener on whichever
titiler.multidim.reader module was imported when it ran. The app
fixture drops every titiler.multidim module from sys.modules and
re-imports, so listing opens before app in a test signature left the
patch on the discarded module and opens stayed empty. Depending on app
orders the fixtures regardless of how a test lists them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…equest

# Conflicts:
#	src/titiler/multidim/mosaic.py
@maxrjones

Copy link
Copy Markdown
Member Author

I'm going to release v0.10.0 without this PR so that it doesn't block the deployment for AIR4US, since they need #166. I'd like to still target releasing this performance improvement this week. I've been defaulting to requiring a review before merging PRs, but also don't want to use up too much of other people's time. Please let me know if I should go based on a different norm regarding reviews.

@chuckwondo

chuckwondo commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

I'm going to release v0.10.0 without this PR so that it doesn't block the deployment for AIR4US, since they need #166. I'd like to still target releasing this performance improvement this week. I've been defaulting to requiring a review before merging PRs, but also don't want to use up too much of other people's time. Please let me know if I should go based on a different norm regarding reviews.

Releasing with the changes from #166 sounds good @maxrjones.

Regarding PR reviews before merging, I'd prefer thorough reviews beforehand, as they can uncover critical issues. Off the top of my head, the ReDoS issue I flagged in #166 comes to mind. I have started reviewing this PR and have uncovered what I believe to be a performance problem. Given that this PR is specifically to address performance, I'd like to finish this review, and have you make adjustments, before merging.

Generally speaking, I'd rather "use up too much of other people's time" up front, because it is generally much less time and cost spent up front to avoid problems to begin with than it is to debug and fix such problems later.

@maxrjones

Copy link
Copy Markdown
Member Author

I'm going to release v0.10.0 without this PR so that it doesn't block the deployment for AIR4US, since they need #166. I'd like to still target releasing this performance improvement this week. I've been defaulting to requiring a review before merging PRs, but also don't want to use up too much of other people's time. Please let me know if I should go based on a different norm regarding reviews.

Releasing with the changes from #166 sounds good @maxrjones.

Regarding PR reviews before merging, I'd prefer thorough reviews beforehand, as they can uncover critical issues. Off the top of my head, the ReDoS issue I flagged in #166 comes to mind. I have started reviewing this PR and have uncovered what I believe to be a performance problem. Given that this PR is specifically to address performance, I'd like to finish this review, and have you make adjustments, before merging.

Generally speaking, I'd rather "use up too much of other people's time" up front, because it is generally much less time and cost spent up front to avoid problems to begin with than it is to debug and fix such problems later.

Thanks, Chuck, that sounds good to me. I tried to determine the norms from the PR history, but it's much more reliable to hear it first hand. I'll update the repo settings accordingly.

Please give me a heads up if you expect that the problem you uncovered will make working on this PR extend into next week, so that I can communicate to the AIR4US devs who requested this work.

@chuckwondo chuckwondo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The five suggestions labeled "ExitStack N of 5" in mosaic.py replace the close() loop with contextlib.ExitStack, so please apply them as one batch. The loop stops at the first reader whose close() raises, which leaves every later reader open, both when a request ends and when validation fails partway. An ExitStack calls every registered __exit__ even when some of them raise, and it also takes over the try/except BaseException cleanup.

Comment thread src/titiler/multidim/mosaic.py
Comment thread src/titiler/multidim/factory.py Outdated
Comment thread src/titiler/multidim/mosaic.py Outdated
Comment thread src/titiler/multidim/mosaic.py
Comment thread src/titiler/multidim/mosaic.py Outdated
Comment thread src/titiler/multidim/mosaic.py Outdated
Comment thread src/titiler/multidim/mosaic.py Outdated
Comment thread src/titiler/multidim/mosaic.py Outdated
Comment thread tests/test_mosaic.py
Comment thread tests/test_mosaic.py
@maxrjones maxrjones mentioned this pull request Oct 8, 2026
4 tasks
maxrjones and others added 4 commits October 8, 2026 15:25
Co-authored-by: Chuck Daniels <cjdaniels4@gmail.com>
Co-authored-by: Chuck Daniels <cjdaniels4@gmail.com>
test_backend_closes_readers_when_validation_fails makes the same two
failing constructions with the same expected exceptions, and also checks
the readers get closed, so test_backend_rejects_unreadable_and_incompatible_sources
no longer adds coverage.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Chuck Daniels <cjdaniels4@gmail.com>
@maxrjones

Copy link
Copy Markdown
Member Author

I'm going to release v0.10.0 without this PR so that it doesn't block the deployment for AIR4US, since they need #166. I'd like to still target releasing this performance improvement this week. I've been defaulting to requiring a review before merging PRs, but also don't want to use up too much of other people's time. Please let me know if I should go based on a different norm regarding reviews.

Releasing with the changes from #166 sounds good @maxrjones.

Regarding PR reviews before merging, I'd prefer thorough reviews beforehand, as they can uncover critical issues. Off the top of my head, the ReDoS issue I flagged in #166 comes to mind. I have started reviewing this PR and have uncovered what I believe to be a performance problem. Given that this PR is specifically to address performance, I'd like to finish this review, and have you make adjustments, before merging.

Generally speaking, I'd rather "use up too much of other people's time" up front, because it is generally much less time and cost spent up front to avoid problems to begin with than it is to debug and fix such problems later.

@chuckwondo do you want to always be pinged again after I address all your comments for another review? i.e., should we continue the cycle until we get to a ✅? The alternative is for me to use my judgement based on the scope of your initial review and how much the PR has changed, and sometimes ask for another review and other times go ahead with merging.

@chuckwondo

Copy link
Copy Markdown
Contributor

@chuckwondo do you want to always be pinged again after I address all your comments for another review? i.e., should we continue the cycle until we get to a ✅? The alternative is for me to use my judgement based on the scope of your initial review and how much the PR has changed, and sometimes ask for another review and other times go ahead with merging.

I'm always happy to take another pass. As I mentioned earlier, I'd prefer taking more time up front rather than rushing something out the door. For what we've done so far for this one, I'm also happy for you to use your best judgement at this point.

@maxrjones

Copy link
Copy Markdown
Member Author

@chuckwondo do you want to always be pinged again after I address all your comments for another review? i.e., should we continue the cycle until we get to a ✅? The alternative is for me to use my judgement based on the scope of your initial review and how much the PR has changed, and sometimes ask for another review and other times go ahead with merging.

I'm always happy to take another pass. As I mentioned earlier, I'd prefer taking more time up front rather than rushing something out the door. For what we've done so far for this one, I'm also happy for you to use your best judgement at this point.

awesome, thanks. Well, I do like to see a ✅ and since you don't mind, I'll stick with the loop 😄

@maxrjones
maxrjones requested a review from chuckwondo October 8, 2026 20:27

@chuckwondo chuckwondo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @maxrjones! I'll leave it up to you as to whether or not you want to apply the perf. gain in the gist I linked, or do it separately (or simply wait for rio-tiler to settle #1022 before bumping).

@maxrjones

Copy link
Copy Markdown
Member Author

Thanks @maxrjones! I'll leave it up to you as to whether or not you want to apply the perf. gain in the gist I linked, or do it separately (or simply wait for rio-tiler to settle #1022 before bumping).

that rio-tiler maintainer seems super responsive, so I'm happy to wait 😆

@maxrjones
maxrjones merged commit 5755761 into main Oct 8, 2026
13 checks passed
@maxrjones
maxrjones deleted the fix/single-open-per-request branch October 8, 2026 20:44
maxrjones added a commit that referenced this pull request Oct 8, 2026
main now opens each dataset once per request (#171), so /tiles, /point
and /info?show_times=true pin 1 repository and 1 dataset open and 9 (or
8) metadata requests instead of 2 and 17 (16).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants