fix(core): skip redundant chain packages after full fallback#526
Merged
JusterZhu merged 1 commit intoJun 20, 2026
Conversation
When a chain package fails and falls back to a full replacement package, the application state is already at or beyond the full package's version. Subsequent chain packages with version ≤ the fallback version are now skipped, avoiding redundant work. Changes: - Add FallbackFullVersion to VersionEntry, DownloadAsset for version tracking - Populate FallbackFullVersion in DownloadPlanBuilder from matching full package - Track fallbackEffectiveVersion in AbstractStrategy.ExecuteAsync loop - Skip chain packages whose version ≤ fallbackEffectiveVersion - Enable StopOnFirstError in ClientTest and UpgradeTest for fallback testing - Use PackageType enum instead of magic number in ClientTest display Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR prevents redundant work during update application when a chain (diff) package fails and falls back to a full replacement package. After a successful full fallback, it tracks the effective version reached and skips subsequent chain packages that are already covered by that fallback version.
Changes:
- Add
FallbackFullVersionto the download/config models and populate it when building the download plan. - Pass
FallbackFullVersionthroughClientStrategyintoVersionEntry. - In
AbstractStrategy.ExecuteAsync, track the highest fallback full version and skip covered chain packages. - Update test programs to enable
DiffPipeline“stop on first error” and adjust test output labeling.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/UpgradeTest/Program.cs | Enables WithStopOnFirstError(true) for the diff pipeline in upgrade test harness. |
| tests/ClientTest/Program.cs | Enables WithStopOnFirstError(true) and adjusts package type display logic in client test harness. |
| src/c#/GeneralUpdate.Core/Strategy/ClientStrategy.cs | Propagates FallbackFullVersion from DownloadAsset into VersionEntry. |
| src/c#/GeneralUpdate.Core/Strategy/AbstractStrategy.cs | Tracks fallback effective version and skips redundant chain packages after full fallback. |
| src/c#/GeneralUpdate.Core/Download/Models/DownloadAsset.cs | Adds FallbackFullVersion to the download asset model. |
| src/c#/GeneralUpdate.Core/Download/DownloadPlanBuilder.cs | Populates FallbackFullVersion by matching chain entries to fallback full packages. |
| src/c#/GeneralUpdate.Core/Configuration/VersionEntry.cs | Adds FallbackFullVersion to the version entry contract for pipeline logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+161
to
+168
| if (fallbackEffectiveVersion != null | ||
| && version.PackageType == (int)PackageType.Chain | ||
| && Semver.TryParse(version.Version, out var versionSv) | ||
| && versionSv <= fallbackEffectiveVersion) | ||
| { | ||
| GeneralTracer.Info($"AbstractStrategy.ExecuteAsync: skipping {version.Version} ({version.Name}) — already covered by fallback full package v{fallbackEffectiveVersion}."); | ||
| continue; | ||
| } |
Comment on lines
+216
to
+221
| if (!string.IsNullOrEmpty(version.FallbackFullVersion) | ||
| && Semver.TryParse(version.FallbackFullVersion, out var ffv) | ||
| && (fallbackEffectiveVersion == null || ffv > fallbackEffectiveVersion)) | ||
| { | ||
| fallbackEffectiveVersion = ffv; | ||
| } |
Comment on lines
+10
to
+11
| using GeneralUpdate.Core.Pipeline; | ||
| using GeneralUpdate.Core.Configuration; |
| foreach (var vi in e.Info.Body) | ||
| { | ||
| var mode = vi.IsCrossVersion == true ? "CVP" : "Chain"; | ||
| var mode = vi.PackageType == (int)PackageType.Full ? "Full" : "Chain"; |
fbc7a16
into
release/1.1.0-package-type-migration
1 check passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a chain package fails and falls back to a full replacement package, the application state is already at or beyond the full package's version. However, the pipeline loop continues processing subsequent chain packages with version ≤ the fallback version, causing redundant work (re-extracting and re-applying the same full package multiple times).
Root Cause
AbstractStrategy.ExecuteAsynciterates over allUpdateVersionsin order, with no awareness that a previous fallback has already brought the application to a higher version. Each chain package failure independently triggers the same full-package fallback.Solution
Track
fallbackEffectiveVersion— the highest version achieved via full-package fallback — and skip any remaining chain packages whose version ≤ that value.Changes
VersionEntry.csFallbackFullVersionpropertyDownloadAsset.csFallbackFullVersionfieldDownloadPlanBuilder.csFallbackFullVersionfrom matching full packageClientStrategy.csFallbackFullVersiontoVersionEntryAbstractStrategy.csfallbackEffectiveVersion, skip covered chain packagestests/ClientTest/Program.csStopOnFirstError, usePackageType.Fullenumtests/UpgradeTest/Program.csStopOnFirstErrorVerification
Test output after fix: