Skip to content
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

Merged
merged 20 commits into from May 10, 2024
Merged

Index V2 consumption #4462

merged 20 commits into from May 10, 2024

Conversation

JohnMcPMS
Copy link
Member

@JohnMcPMS JohnMcPMS commented May 8, 2024

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 [aka list 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 in winget-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

@JohnMcPMS JohnMcPMS requested a review from a team as a code owner May 8, 2024 17:36
### 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.
Copy link
Contributor

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?

Copy link
Member Author

@JohnMcPMS JohnMcPMS May 8, 2024

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 },
};
Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Member Author

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);
Copy link
Contributor

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

Copy link
Member Author

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;
}
Copy link
Contributor

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?

Copy link
Member Author

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);
Copy link
Contributor

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

msftrubengu
msftrubengu previously approved these changes May 9, 2024
@@ -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";
Copy link
Contributor

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?

Copy link
Member Author

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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

triggers OCD

Copy link
Member Author

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
Copy link
Contributor

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.

yao-msft
yao-msft previously approved these changes May 10, 2024
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
Copy link
Contributor

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?

Copy link
Member Author

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.
Copy link
Contributor

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

Copy link
Member Author

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.

@JohnMcPMS JohnMcPMS merged commit 5fe31fc into microsoft:master May 10, 2024
8 checks passed
@JohnMcPMS JohnMcPMS deleted the index-v2-use branch May 10, 2024 19:14
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.

None yet

4 participants