Skip to content

Batch 4: Download subsystem integration — replace old DownloadManager#368

Merged
JusterZhu merged 1 commit into
masterfrom
batch-4-download-integration
May 24, 2026
Merged

Batch 4: Download subsystem integration — replace old DownloadManager#368
JusterZhu merged 1 commit into
masterfrom
batch-4-download-integration

Conversation

@JusterZhu
Copy link
Copy Markdown
Collaborator

Summary

Core download refactoring batch. Replaces the old DownloadManager/DownloadTask pattern in ClientUpdateStrategy with the new layered download abstractions, and creates the cross-version package selection logic.

New Files

DownloadPlanBuilder

  • Cross-version package selection (jump directly to target)
  • Version chain building (sequential upgrades)
  • Frozen package filtering
  • MinClientVersion compatibility check
  • Forced update detection

HttpDownloadSource

  • Implements IDownloadSource
  • Wraps version validation for both client and upgrade versions
  • Converts VersionInfo to DownloadAsset

Refactored

DefaultDownloadOrchestrator

  • Now accepts DownloadPlan instead of raw URLs
  • Integrates SHA256 verification via DefaultDownloadPipeline per asset

IDownloadOrchestrator

  • Interface updated: ExecuteAsync(DownloadPlan, ...) instead of ExecuteAsync(List, ...)

ClientUpdateStrategy

  • Uses HttpDownloadSource + DownloadPlanBuilder + DefaultDownloadOrchestrator
  • Removed old DownloadAsync() method using DownloadManager
  • Removed unused CheckUpgrade/CheckForcibly methods

DownloadManager

  • Marked [Obsolete] — still used by OSSUpdateStrategy and SilentUpdateMode

Build

  • dotnet build src/c#/GeneralUpdate.slnx — 0 errors

Closes #367

- Create DownloadPlanBuilder: cross-version selection, version chain,
  frozen package filtering, MinClientVersion compatibility check
- Create HttpDownloadSource: bridges VersionService → IDownloadSource,
  validates both client and upgrade versions in one call
- Refactor DefaultDownloadOrchestrator: accept DownloadPlan instead of
  raw URLs, integrate SHA256 verification via DefaultDownloadPipeline
- Update IDownloadOrchestrator interface to accept DownloadPlan
- Refactor ClientUpdateStrategy: replace old DownloadManager/DownloadTask
  with HttpDownloadSource + DownloadPlanBuilder + DefaultDownloadOrchestrator
- Mark DownloadManager as [Obsolete] — still used by OSS and Silent
  (to be removed in later batches)

Closes #367
Copilot AI review requested due to automatic review settings May 24, 2026 10:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 is a “Batch 4” refactor of the C# download/update path in GeneralUpdate.Core, moving ClientUpdateStrategy off the legacy DownloadManager/DownloadTask approach and onto the newer layered download abstractions (IDownloadSourceDownloadPlanIDownloadOrchestrator), with added SHA256 verification in the orchestrator and a new DownloadPlanBuilder intended to support cross-version package selection.

Changes:

  • Refactors ClientUpdateStrategy to use HttpDownloadSource, DownloadPlanBuilder, and DefaultDownloadOrchestrator (and removes the legacy DownloadAsync() method).
  • Introduces HttpDownloadSource (new file) and DownloadPlanBuilder (new file).
  • Updates IDownloadOrchestrator + DefaultDownloadOrchestrator to execute a DownloadPlan and perform SHA256 verification.

Reviewed changes

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

Show a summary per file
File Description
src/c#/GeneralUpdate.Core/Strategy/ClientUpdateStrategy.cs Switches client workflow to new download abstractions and removes legacy DownloadAsync() path.
src/c#/GeneralUpdate.Core/Download/Sources/HttpDownloadSource.cs Adds an HTTP-backed IDownloadSource that calls the version validation API and maps to DownloadAsset.
src/c#/GeneralUpdate.Core/Download/Orchestrators/DefaultDownloadOrchestrator.cs Updates orchestrator to download from a DownloadPlan and verify SHA256 via DefaultDownloadPipeline.
src/c#/GeneralUpdate.Core/Download/DownloadPlanBuilder.cs Adds logic to build an ordered download plan (cross-version selection + version chain).
src/c#/GeneralUpdate.Core/Download/DownloadManager.cs Marks legacy DownloadManager as [Obsolete].
src/c#/GeneralUpdate.Core/Download/Abstractions/IDownloadOrchestrator.cs Changes orchestrator contract to accept DownloadPlan instead of URL lists.

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

Comment on lines +134 to 136
// Dispatch update info event
var updateInfoArgs = new UpdateInfoEventArgs(null);
EventManager.Instance.Dispatch(this, updateInfoArgs);
Comment on lines +176 to 180
// Build process info for the upgrade process
_configInfo.ProcessInfo = JsonSerializer.Serialize(
ConfigurationMapper.MapToProcessInfo(
_configInfo, new List<VersionInfo>(),
BlackListManager.Instance.BlackFormats.ToList(),
Comment on lines +190 to +200
// Download via orchestrator (replaces old DownloadManager)
GeneralTracer.Info($"ClientUpdateStrategy: downloading {downloadPlan.Assets.Count} asset(s).");
var httpClient = new System.Net.Http.HttpClient();
try
{
case true when _configInfo.IsMainUpdate:
GeneralTracer.Info("ClientUpdateStrategy: both upgrade+main -- downloading and executing.");
await DownloadAsync();
await SafeReportDownloadCompletedAsync(hooksCtx).ConfigureAwait(false);
await _osStrategy.ExecuteAsync();
await SafeOnBeforeStartAppAsync(hooksCtx).ConfigureAwait(false);
_osStrategy.StartApp();
break;
case true when !_configInfo.IsMainUpdate:
GeneralTracer.Info("ClientUpdateStrategy: upgrade-only -- downloading and executing.");
await DownloadAsync();
await SafeReportDownloadCompletedAsync(hooksCtx).ConfigureAwait(false);
await _osStrategy.ExecuteAsync();
break;
case false when _configInfo.IsMainUpdate:
GeneralTracer.Info("ClientUpdateStrategy: main-only -- starting updater.");
await SafeOnBeforeStartAppAsync(hooksCtx).ConfigureAwait(false);
_osStrategy.StartApp();
break;
var orchestrator = new Download.Orchestrators.DefaultDownloadOrchestrator(httpClient);
await orchestrator.ExecuteAsync(downloadPlan, _configInfo.TempPath).ConfigureAwait(false);
}
finally
{
httpClient.Dispose();
Comment on lines +76 to +85
private static DownloadAsset MapVersionInfo(VersionInfo v)
{
return new DownloadAsset(
Name: v.Name ?? v.Version ?? "unknown",
Url: v.Url ?? string.Empty,
Size: v.Size ?? 0,
SHA256: v.Hash,
Version: v.Version ?? "0.0.0",
IsForcibly: v.IsForcibly == true
);
Comment on lines 43 to 46
var sw = Stopwatch.StartNew();
var results = new List<DownloadResult>();
var sem = new SemaphoreSlim(maxConcurrency);
long totalBytes = 0;
Comment on lines +60 to +70
private static List<DownloadAsset> BuildVersionChain(IEnumerable<DownloadAsset> assets, string currentVersion)
{
var current = ParseVersion(currentVersion);

return assets
.Where(a =>
{
var pv = ParseVersion(a.Version);
if (pv == null) return false;
return pv > current;
})
@JusterZhu JusterZhu merged commit 8d63132 into master May 24, 2026
1 check passed
@JusterZhu JusterZhu deleted the batch-4-download-integration branch May 24, 2026 10:26
JusterZhu added a commit that referenced this pull request May 24, 2026
Fixes from PR #368 (Batch 4):
1. UpdateInfoEventArgs: make VersionRespDTO nullable to avoid null ref
2. ClientUpdateStrategy: build VersionInfo list from DownloadAssets
   instead of passing empty list to ProcessInfo constructor
3. ClientUpdateStrategy: use injected _orchestrator if available,
   fall back to creating one with HttpClient
5. DefaultDownloadOrchestrator: ensure destDir exists (Directory.CreateDirectory)
   and dispose SemaphoreSlim (using)
6. DownloadPlanBuilder: guard against invalid currentVersion string

Fixes from PR #380 (Batch 10):
8. OSSUpdateStrategy: set zip filename to match Decompress() expectations
9. OSSUpdateStrategy: throw clear exception when URL is null/empty
10. OSSUpdateStrategy: set HttpClient.Timeout to 60s to match old behavior

Closes #386
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.

Batch 4: Download subsystem integration — replace old DownloadManager

2 participants