Skip to content

feat(lsp): add per-dependency timeout isolation for registry fetches#46

Merged
bug-ops merged 2 commits intomainfrom
feat/per-dependency-timeout
Dec 26, 2025
Merged

feat(lsp): add per-dependency timeout isolation for registry fetches#46
bug-ops merged 2 commits intomainfrom
feat/per-dependency-timeout

Conversation

@bug-ops
Copy link
Owner

@bug-ops bug-ops commented Dec 26, 2025

Summary

  • Prevents slow packages from blocking the entire fetch queue
  • Each package fetch wrapped in individual timeout (default: 5s)
  • Configurable concurrency limit (default: 20 concurrent requests)
  • Bounds validation for security (timeout: 1-300s, concurrency: 1-100)

Problem

Previously, fetch_latest_versions_parallel() used buffer_unordered(10) without timeout isolation. If one package registry was slow (30+ seconds), it would block a concurrency slot and delay processing of all other packages.

Solution

// Each package fetch wrapped in timeout
match tokio::time::timeout(timeout, registry.get_versions(&name)).await {
    Ok(Ok(versions)) => { /* success */ }
    Ok(Err(e)) => { tracing::warn!("Failed to fetch"); None }
    Err(_) => { tracing::warn!("Fetch timed out"); None }
}

Performance Impact

Scenario Before After
50 deps, 1 slow package (30s) 30+ seconds ~5 seconds
Normal operation No change No change

Configuration

{
  "cache": {
    "fetch_timeout_secs": 10,
    "max_concurrent_fetches": 50
  }
}

Test plan

  • test_fetch_latest_versions_parallel_with_timeout - Timeout works
  • test_fetch_latest_versions_parallel_fast_packages_not_blocked - Fast packages complete
  • test_fetch_partial_success_with_mixed_outcomes - Error handling
  • test_cache_config_fetch_timeout_clamped_min/max - Bounds validation
  • test_cache_config_max_concurrent_clamped_min/max - Bounds validation
  • All 239 tests pass
  • Clippy clean

Prevents slow packages from blocking the entire fetch queue by wrapping
each package fetch in an individual timeout. Previously, a single slow
package (30s+) would block a concurrency slot and delay all other packages.

Changes:
- Add configurable `fetch_timeout_secs` (default: 5s, range: 1-300s)
- Add configurable `max_concurrent_fetches` (default: 20, range: 1-100)
- Wrap each registry fetch in `tokio::time::timeout()`
- Add bounds validation with clamping for security
- Add comprehensive tests for timeout behavior and edge cases

Performance impact:
- Before: 50-dep manifest with 1 slow package → 30+ seconds
- After: 50-dep manifest with 1 slow package → ~5 seconds

User configuration:
```json
{
  "cache": {
    "fetch_timeout_secs": 10,
    "max_concurrent_fetches": 50
  }
}
```
@github-actions github-actions bot added rust Rust code changes needs-review Needs review size: XL 500-1000 lines changed labels Dec 26, 2025
@codecov-commenter
Copy link

codecov-commenter commented Dec 26, 2025

Codecov Report

❌ Patch coverage is 68.60465% with 81 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/deps-lsp/src/document/lifecycle.rs 56.25% 77 Missing ⚠️
crates/deps-lsp/src/config.rs 95.12% 4 Missing ⚠️

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #46      +/-   ##
==========================================
- Coverage   85.04%   84.99%   -0.05%     
==========================================
  Files          56       56              
  Lines       15409    15652     +243     
==========================================
+ Hits        13105    13304     +199     
- Misses       2304     2348      +44     
Flag Coverage Δ
deps-cargo 79.75% <ø> (ø)
deps-core 90.00% <ø> (ø)
deps-go 84.99% <68.60%> (-0.05%) ⬇️
deps-lsp 78.23% <68.60%> (+0.25%) ⬆️
deps-npm 89.56% <ø> (ø)
deps-pypi 86.70% <ø> (ø)
overall 84.99% <68.60%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
crates/deps-lsp/src/config.rs 98.10% <95.12%> (-1.05%) ⬇️
crates/deps-lsp/src/document/lifecycle.rs 55.57% <56.25%> (+6.50%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Add Loading Indicators feature to README
- Document fetch_timeout_secs and max_concurrent_fetches options
- Document loading_indicator configuration section
- Add Configuration Reference table with all new options
- Fix outdated ecosystem registration path in templates/README.md
@github-actions github-actions bot added the documentation Improvements or additions to documentation label Dec 26, 2025
@bug-ops bug-ops merged commit 06bc52d into main Dec 26, 2025
20 checks passed
@bug-ops bug-ops deleted the feat/per-dependency-timeout branch December 26, 2025 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation needs-review Needs review rust Rust code changes size: XL 500-1000 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants