-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Index V2 consumption #4462
Index V2 consumption #4462
Conversation
### indexV2 | ||
|
||
This feature enables the `winget` source to retrieve the V2 index, which is significantly smaller. | ||
Regardless of the state of this feature, if the index on the machine contains a V2 index, it will be used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify - If the V2 index is outdated, and a newer V1 index is available, will the V1 index be used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Editing for more complete answer]
If the feature is enabled, the V2 index will always be preferred if it exists.
If the feature is disabled, a newer V1 index will replace the V2 index when it becomes available.
{ "windowsFeature", false }, | ||
{ "resume", false }, | ||
{ "reboot", false }, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this table would need to be updated anytime an experimental feature is added or removed; Is there a way to make this dynamic? In fact, couldn't you just use an empty hashtable since the forcedExperimentalFeatures
should add whatever experimental features you need to the hashtable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that an empty table is currently equivalent, but that also means that not updating it is equivalent. I'm not trying to change that right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But since I was looking at the file and then touched it, removed them.
ConfigureFeature(settingsJson, "directMSI", status); | ||
ConfigureFeature(settingsJson, "windowsFeature", status); | ||
ConfigureFeature(settingsJson, "resume", status); | ||
ConfigureFeature(settingsJson, "reboot", status); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above comment - seems like this could be a pain to maintain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear, I'm not changing anything about that fact one way or the other here.
if (!AreChannelsSupported(index)) | ||
{ | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You repeat this a few times. Would a RETURNIF(condition , [return value])
macro be useful to reduce code at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't feel like that is worth the additional cognitive load of knowing what it does to save the lines.
@@ -149,7 +150,7 @@ namespace AppInstaller::Settings | |||
SETTINGMAPPING_SPECIALIZATION(Setting::ProgressBarVisualStyle, std::string, VisualStyle, VisualStyle::Accent, ".visual.progressBar"sv); | |||
SETTINGMAPPING_SPECIALIZATION(Setting::AnonymizePathForDisplay, bool, bool, true, ".visual.anonymizeDisplayedPaths"sv); | |||
// Source | |||
SETTINGMAPPING_SPECIALIZATION_POLICY(Setting::AutoUpdateTimeInMinutes, uint32_t, std::chrono::minutes, 5min, ".source.autoUpdateIntervalInMinutes"sv, ValuePolicy::SourceAutoUpdateIntervalInMinutes); | |||
SETTINGMAPPING_SPECIALIZATION_POLICY(Setting::AutoUpdateTimeInMinutes, uint32_t, std::chrono::minutes, 15min, ".source.autoUpdateIntervalInMinutes"sv, ValuePolicy::SourceAutoUpdateIntervalInMinutes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a comment about the code, just a reminder for @denelon that this change will require a docs update - https://learn.microsoft.com/en-us/windows/package-manager/winget/settings#autoupdateintervalinminutes
@@ -70,6 +72,14 @@ namespace AppInstaller::Manifest | |||
return "versionData.mszyml"sv; | |||
} | |||
|
|||
std::filesystem::path PackageVersionDataManifest::GetRelativeDirectoryPath(std::string_view packageIdentifier, std::string_view manifestHash) | |||
{ | |||
std::filesystem::path result = "packages"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static constexpr std::string_view?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it was to be used elsewhere, but this function is meant to prevent that need.
@@ -52,6 +52,8 @@ namespace AppInstaller::Settings | |||
return userSettings.Get<Setting::EFConfigureSelfElevation>(); | |||
case ExperimentalFeature::Feature::StoreDownload: | |||
return userSettings.Get<Setting::EFStoreDownload>(); | |||
case ExperimentalFeature::Feature::IndexV2: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
triggers OCD
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to assume that my lazy "Accept Both Changes" click in Code that put my case first is the issue here. 🦪
@@ -31,375 +31,894 @@ namespace AppInstaller::Repository::Microsoft | |||
std::weak_ptr<SQLiteIndexSource> m_source; | |||
}; | |||
|
|||
// The IPackageVersion impl for SQLiteIndexSource. | |||
struct PackageVersion : public SourceReference, public IPackageVersion | |||
namespace V1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure this is easier, but it might be worthy to have them in separate files for maintainability.
…o content type mapping so that they will be served
This comment has been minimized.
This comment has been minimized.
Regardless of the state of this feature, if the index on the machine contains a V2 index, it will be used. | ||
If there is a bug with the V2 index stopping the `winget` CLI from working, disable the feature in your settings file and run this command: | ||
``` | ||
> winget uninstall -s msstore Microsoft.Winget.Source_8wekyb3d8bbwe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "-s msstore", is this listed in store source?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that was an intentional "if the winget source is broken, lets avoid using it" flag. Commands targeting the local data don't really need a source, but we don't have a way to use a null one.
|
||
namespace details | ||
{ | ||
// The base for the package objects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: seems like wrong description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it isn't wrong, but it probably made more sense before I refactored it away from the things that inherit it.
Change
This change adds the ability to actually use the V2 index database. This primarily required fixing the ignored search functionality from the previous PR and updating the
ISource
implementation to be aware of V2 and how to retrieve the package version manifest files. Additionally, a few places in the code were updated to avoid requesting all of the package versions when we could instead use only the latest version. This prevents the need to retrieve the package version file at all, which is the goal for all read-only operations (search
,list
,update
[akalist
but filtered to things with updates]). In reality, we do need to get the package version files when we need to do ARP version mapping, but that constitutes only 5% of the total packages inwinget-pkgs
currently.While the V2 usage code is always enabled, an experimental feature (
indexV2
) is required to attempt to retrieve the V2 index from the CDN. Disabling this feature should naturally transition one back to V1 on the next update attempt.File caching, based on the known SHA256 hash of the file, is added as a general utility. This is then used for V1 manifest files and also for V2 package version data and manifest files. While the files are generally small, it is not uncommon for them to be used a few times over a short period.
Thanks to @msftrubengu for pointing out that I forgot the include the exports in the .def file in the previous PR. 🥇
Validation
Added many new unit tests and updated many existing unit tests.
Updated E2E tests to generate a V2 index in addition to the V1, and added a test pass that runs all of the existing E2E tests using the V2 index.
Microsoft Reviewers: Open in CodeFlow