Skip to content

bundles: prefetch retained Itar cache entries concurrently#1379

Merged
CraftSpider merged 2 commits into
tectonic-typesetting:masterfrom
hhh2210:perf-concurrent-bundle-prefetch
Jul 13, 2026
Merged

bundles: prefetch retained Itar cache entries concurrently#1379
CraftSpider merged 2 commits into
tectonic-typesetting:masterfrom
hhh2210:perf-concurrent-bundle-prefetch

Conversation

@hhh2210

@hhh2210 hhh2210 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR lets the indexed-tar bundle cache refetch a previously used working set concurrently when its metadata is still present but the cached file blobs are missing.

It does not change a first-ever build on a new cache because there is no learned manifest to replay. TTBNetBundle is also unchanged.

Why

The TeX engine discovers support files synchronously. With an indexed-tar bundle, every cache miss becomes a separate HTTP byte-range request, so a high-latency connection pays the round-trip cost once per file.

After one successful build, the cache already knows which names were requested. Replaying that bounded list concurrently turns the later engine requests into local cache hits.

Implementation

  • BundleCache keeps an append-only manifest keyed by bundle location. It records successful warm hits and downloads, deduplicates entries when loading, and caps the learned set at 512 names.
  • Prefetching is opt-in through CachableBundle::supports_batch_open, so backends without a concurrent implementation retain their existing on-demand behavior.
  • ItarBundle uses a bounded worker pool with one range reader per worker. The default is 16 workers, with a hard cap of 64.
  • Cache batches contain at most 64 files. The Itar backend further caps one batch at 64 MiB of declared file data.
  • Files are written to a process-specific temporary path and renamed into place. Partial temporary files are removed.

Failure behavior

  • only_cached mode never starts a network prefetch.
  • A missing, malformed, or stale manifest falls back to the existing on-demand path.
  • The first final network or local-write failure stops new prefetch work. Files left uncached are retried normally if the engine requests them.
  • A worker panic or spawn failure leaves its entries uncached instead of failing the build.

Review guide

The two commits are intentionally separated:

  1. bundles: connect Itar reader for cached indexes fixes the cached-index reader == None panic and adds its regression test.
  2. bundles: prefetch retained Itar cache entries adds the opt-in API, cache-side manifest handling, and Itar worker pool.

For the feature commit, the shortest review path is:

  1. crates/bundles/src/lib.rs: the optional batch capability.
  2. crates/bundles/src/cache/prefetch.rs: manifest rules, cache filtering, fallback, and temporary-file placement.
  3. crates/bundles/src/itar/batch.rs: concurrency and memory bounds.
  4. The small call-site changes in cache.rs and itar.rs.

Validation

cargo fmt --all -- --check
cargo test -p tectonic_bundles --all-features
# 5 passed
cargo clippy --all --all-targets --all-features -- --deny warnings

A manual high-latency measurement used the same patched binary and identical cache state in both arms: retained bundle index and manifest, missing file blobs. Only TECTONIC_PREFETCH_CONCURRENCY changed.

concurrency wall time
1 125.31 s
16 9.87 s

These absolute times depend on network latency. The relevant result is the reduction in serialized range-request waits for this specific retained-metadata cache state.

Related: #446.

Copilot AI review requested due to automatic review settings June 30, 2026 12:55

Copilot AI 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.

Pull request overview

This PR accelerates cold-cache builds by teaching the bundles layer to prefetch a previously-recorded “working set” of bundle files concurrently, so the TeX engine’s later synchronous reads mostly hit the local cache instead of issuing hundreds of serial HTTP range requests.

Changes:

  • Add a CachableBundle::batch_open API (default serial implementation) to support batch fetching of bundle files.
  • Implement concurrent batch downloading in ItarBundle (worker pool + per-worker range reader) and refactor retrying range reads into a shared helper.
  • Add a per-bundle prefetch manifest in BundleCache and a one-time-per-session prefetch step before the first file lookup.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
crates/bundles/src/lib.rs Introduces batch_open on CachableBundle with a correct serial default implementation.
crates/bundles/src/itar.rs Adds concurrent batch_open override for the .tar network bundle and shared retrying range-read helper.
crates/bundles/src/cache.rs Records fetched file names to a manifest and replays them via prefetch() to warm the on-disk cache.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/bundles/src/itar.rs
Comment thread crates/bundles/src/itar.rs Outdated
Comment thread crates/bundles/src/cache.rs Outdated
Comment thread crates/bundles/src/cache.rs Outdated
@hhh2210 hhh2210 changed the title bundles: concurrently prefetch the cold-cache working set (~7x faster cold builds) bundles: concurrently prefetch the cold-cache working set (~12.7x faster cold builds) Jun 30, 2026
@hhh2210

hhh2210 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@CraftSpider ready for review

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.27950% with 144 lines in your changes missing coverage. Please review.
✅ Project coverage is 29.90%. Comparing base (ab5ef51) to head (8419491).

Files with missing lines Patch % Lines
crates/bundles/src/itar/batch.rs 44.44% 65 Missing ⚠️
crates/bundles/src/cache/prefetch.rs 65.74% 32 Missing and 5 partials ⚠️
crates/bundles/src/itar.rs 56.36% 24 Missing ⚠️
crates/bundles/src/lib.rs 15.00% 17 Missing ⚠️
crates/bundles/src/cache.rs 95.45% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1379      +/-   ##
==========================================
+ Coverage   29.85%   29.90%   +0.05%     
==========================================
  Files         273      275       +2     
  Lines      180530   180810     +280     
  Branches   180530   180810     +280     
==========================================
+ Hits        53889    54064     +175     
- Misses      54416    54525     +109     
+ Partials    72225    72221       -4     
Components Coverage Δ
tectonic 51.35% <ø> (ø)
bridge_core 34.25% <ø> (ø)
bridge_flate 38.82% <ø> (ø)
bridge_fontconfig 95.67% <ø> (ø)
bridge_freetype2 92.70% <ø> (ø)
bridge_graphite2 42.47% <ø> (ø)
bridge_harfbuzz 82.83% <ø> (ø)
bridge_icu ∅ <ø> (∅)
bridge_png 100.00% <ø> (ø)
bundles 40.84% <55.27%> (+4.76%) ⬆️
cfg_support 94.84% <ø> (ø)
dep_support 0.00% <ø> (ø)
docmodel 84.87% <ø> (ø)
engine_bibtex 67.46% <ø> (ø)
engine_spx2html 0.00% <ø> (ø)
engine_xdvipdfmx 64.30% <ø> (ø)
engine_xetex 35.73% <ø> (ø)
errors 47.61% <ø> (ø)
geturl 28.20% <ø> (ø)
io_base 76.11% <ø> (ø)
pdf_io 14.19% <ø> (+0.02%) ⬆️
status_base 81.92% <ø> (ø)
xdv 55.28% <ø> (ø)
xetex_format 23.31% <ø> (ø)
xetex_layout 59.57% <ø> (ø)

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hhh2210
hhh2210 force-pushed the perf-concurrent-bundle-prefetch branch from 37eb9e3 to d6d4746 Compare July 13, 2026 06:53
@hhh2210
hhh2210 force-pushed the perf-concurrent-bundle-prefetch branch from d6d4746 to 8419491 Compare July 13, 2026 07:37
@hhh2210 hhh2210 changed the title bundles: concurrently prefetch the cold-cache working set (~12.7x faster cold builds) bundles: prefetch retained Itar cache entries concurrently Jul 13, 2026
@hhh2210

hhh2210 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Status update since my earlier ping: this is now ready for code review. The branch is rebased onto current master and reduced to two focused commits. The existing review feedback is addressed, and the PR body now documents the narrower retained-metadata cache scope and current validation. The fork workflow is waiting for maintainer approval before GitHub will start it.

@CraftSpider CraftSpider 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 for the change! Improving our performance is a pretty significant goal right now, so this looks like a great speedup.

@CraftSpider
CraftSpider merged commit d047310 into tectonic-typesetting:master Jul 13, 2026
28 checks passed
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.

3 participants