Skip to content

Improve self-update package downloads#348

Merged
ModerRAS merged 2 commits into
masterfrom
codex/multipart-self-update-download
May 12, 2026
Merged

Improve self-update package downloads#348
ModerRAS merged 2 commits into
masterfrom
codex/multipart-self-update-download

Conversation

@ModerRAS

@ModerRAS ModerRAS commented May 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • stream self-update package downloads to disk instead of buffering packages and decompressed tar payloads in memory
  • add automatic HTTP Range probing and multipart downloads for large update assets, with fallback to single-stream downloads
  • add tests for streaming package extraction and multipart range merge behavior

Validation

  • dotnet test TelegramSearchBot.Test\TelegramSearchBot.Test.csproj --filter "FullyQualifiedName~SelfUpdateBootstrapTests"
  • dotnet build TelegramSearchBot.sln --configuration Release

Summary by CodeRabbit

  • New Features

    • Efficient multipart range-based downloading for update artifacts with staged cache, temp-file handling, integrity verification, atomic promotion, and safe cleanup.
    • Decompression now streams packages directly to improve memory usage and extraction reliability.
  • Tests

    • Expanded tests covering package creation, Zstd-compressed tar extraction, partial-range downloads (including merge/fallback behavior), and stream consumption behavior.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 388041a2-bd7f-4e20-9c80-327ebd83f1a5

📥 Commits

Reviewing files that changed from the base of the PR and between 27c930e and 1ef1e5e.

📒 Files selected for processing (2)
  • TelegramSearchBot.Test/Service/Update/SelfUpdateBootstrapTests.cs
  • TelegramSearchBot/Service/Update/SelfUpdateBootstrap.Windows.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • TelegramSearchBot/Service/Update/SelfUpdateBootstrap.Windows.cs

📝 Walkthrough

Walkthrough

Adds range-probing and multipart-download support to the Windows self-update bootstrap, stages downloads in a per-update package cache with safe temp-file semantics, simplifies package decompression to a stream, and adds tests that build and validate Zstd-compressed tar packages and HTTP range behaviors.

Changes

Multipart Download and Self-Update Refactor

Layer / File(s) Summary
Download infrastructure: imports, constants, and types
TelegramSearchBot/Service/Update/SelfUpdateBootstrap.Windows.cs
HTTP header imports, multipart download configuration constants (threshold, part size, parallelism), and internal DownloadProbe and DownloadRange value types for range capability detection and range computation.
Download orchestration: probing, single-stream, and multipart routing
TelegramSearchBot/Service/Update/SelfUpdateBootstrap.Windows.cs
New download path writes to .partial, probes server range support via single-byte GET, routes to single-stream or multipart download based on size/capability, performs per-part downloads using Range headers, merges parts, verifies on-disk lengths, and ensures temp-file cleanup on errors.
Update preparation, updater download, decompression, and file helpers
TelegramSearchBot/Service/Update/SelfUpdateBootstrap.Windows.cs
Update staging uses a per-update packages cache directory; updater binary downloads to .download, checksum-verifies from disk, and is atomically moved into cache; DecompressPackage now returns a decompression stream; GetPackageCacheFileName and DeleteFileIfExists added.
Test helpers and download/extraction tests
TelegramSearchBot.Test/Service/Update/SelfUpdateBootstrapTests.cs
Expanded test imports for tar/Zstd/JSON and HTTP mocking. CreateTestPackage builds Zstd-compressed tar with an UpdateManifest; WriteTarEntry writes normalized tar entries; RangeHttpMessageHandler mocks range responses and records ranges. Tests validate decompression early-return, Zstd tar extraction with nested paths, multipart range downloads merging parts, and fallback to single-stream when ranges unsupported.

Sequence Diagram(s)

sequenceDiagram
  participant SelfUpdateBootstrap
  participant RemoteServer
  participant Disk
  SelfUpdateBootstrap->>RemoteServer: GET Range: bytes=0-0 (probe)
  RemoteServer-->>SelfUpdateBootstrap: 206 + Content-Range / Content-Length or no-range support
  alt Server supports ranges AND file > threshold
    SelfUpdateBootstrap->>SelfUpdateBootstrap: Compute download ranges
    loop For each part (parallel)
      SelfUpdateBootstrap->>RemoteServer: GET Range: bytes=start-end
      RemoteServer-->>SelfUpdateBootstrap: 206 Partial Content
      SelfUpdateBootstrap->>Disk: Write part file
    end
    SelfUpdateBootstrap->>Disk: Merge part files into ".partial"
    SelfUpdateBootstrap->>Disk: Delete part files
  else Single download
    SelfUpdateBootstrap->>RemoteServer: GET full file
    RemoteServer-->>SelfUpdateBootstrap: 200 OK Full content
    SelfUpdateBootstrap->>Disk: Write to ".partial"
  end
  SelfUpdateBootstrap->>Disk: Verify total length
  SelfUpdateBootstrap->>Disk: Move ".partial" to final cache path
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • ModerRAS/TelegramSearchBot#294: Modifies Windows self-update implementation and Zstd tar package handling/decompression logic with direct code-level overlap.
  • ModerRAS/TelegramSearchBot#323: Refactors update flow and touches SelfUpdateBootstrap.Windows.cs; related to download/extraction logic and types.

Poem

A rabbit nibbles bytes with cheer,
Splitting ranges far and near,
Parts stitch back into a file,
Temp names gone, the cache can smile —
🐇📦✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Improve self-update package downloads' directly addresses the main focus of the PR: streaming downloads instead of buffering, adding HTTP Range support, and multipart downloads for update packages.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/multipart-self-update-download

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
TelegramSearchBot.Test/Service/Update/SelfUpdateBootstrapTests.cs (1)

715-747: ⚡ Quick win

Cover the fallback path, not just the happy-path merge.

This test proves multipart merge works, but it never exercises the new ProbeDownloadAsync / DownloadFileFromUriAsync branch that should fall back to single-stream when ranges are unsupported or a part response is invalid. Since fallback is a core behavior of this PR, add one handler variant that returns 200 OK to the probe or a bad range response and assert the final file still downloads correctly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@TelegramSearchBot.Test/Service/Update/SelfUpdateBootstrapTests.cs` around
lines 715 - 747, Add a negative-path variant of the existing test that forces
the fallback branch in DownloadFileInPartsAsync (which calls ProbeDownloadAsync
and may call DownloadFileFromUriAsync) by using an HTTP handler that either
returns 200 OK for the probe request (no Range header) or returns an invalid/bad
response for range requests; invoke the same private static helper as in
DownloadFileInPartsAsync_RequestsRangesAndMergesFile to run the download, then
assert the resulting file contents match the payload and that the handler
recorded that the multipart range flow was not used (e.g., RangeRequests count
is 0 or only a single full-file request was made) to prove the fallback
single-stream download path is executed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@TelegramSearchBot/Service/Update/SelfUpdateBootstrap.Windows.cs`:
- Around line 415-417: The 206 handling in the DownloadProbe path currently
trusts any PartialContent with a matching Length; change it to validate
response.Content.Headers.ContentRange so ContentRange.From and ContentRange.To
exactly equal the requested byte range (and ContentRange.Length equals
rangeLength) before returning new DownloadProbe(true, rangeLength); otherwise
treat it as a bad range (reject range mode/fall back). Apply the same strict
Content-Range From/To validation in the per-part code path (the similar 206
handling around the 512-521 region) so both DownloadProbe and per-part downloads
only accept responses whose ContentRange.From/To exactly match the requested
start/end.

---

Nitpick comments:
In `@TelegramSearchBot.Test/Service/Update/SelfUpdateBootstrapTests.cs`:
- Around line 715-747: Add a negative-path variant of the existing test that
forces the fallback branch in DownloadFileInPartsAsync (which calls
ProbeDownloadAsync and may call DownloadFileFromUriAsync) by using an HTTP
handler that either returns 200 OK for the probe request (no Range header) or
returns an invalid/bad response for range requests; invoke the same private
static helper as in DownloadFileInPartsAsync_RequestsRangesAndMergesFile to run
the download, then assert the resulting file contents match the payload and that
the handler recorded that the multipart range flow was not used (e.g.,
RangeRequests count is 0 or only a single full-file request was made) to prove
the fallback single-stream download path is executed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fa7ed685-f350-4873-8a6c-ab695a9fa604

📥 Commits

Reviewing files that changed from the base of the PR and between 28ab45e and 27c930e.

📒 Files selected for processing (2)
  • TelegramSearchBot.Test/Service/Update/SelfUpdateBootstrapTests.cs
  • TelegramSearchBot/Service/Update/SelfUpdateBootstrap.Windows.cs

Comment thread TelegramSearchBot/Service/Update/SelfUpdateBootstrap.Windows.cs
@github-actions

github-actions Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

PR Check Report

Summary

Test Results

Platform Status Details
Ubuntu Passed Tests passed, artifacts uploaded
Windows Passed Tests passed, artifacts uploaded

Code Quality

  • Code formatting check
  • Security vulnerability scan
  • Dependency analysis
  • Code coverage collection

Test Artifacts

  • Test results artifacts count: 2
  • Code coverage uploaded to Codecov

Links


This report is auto-generated by GitHub Actions

@ModerRAS ModerRAS merged commit dcd0727 into master May 12, 2026
5 checks passed
@ModerRAS ModerRAS deleted the codex/multipart-self-update-download branch May 12, 2026 10:23
@coderabbitai coderabbitai Bot mentioned this pull request May 14, 2026
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