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

Refactor pinning evaluation #4151

Merged
merged 5 commits into from
Feb 8, 2024
Merged

Conversation

JohnMcPMS
Copy link
Member

@JohnMcPMS JohnMcPMS commented Feb 7, 2024

Change

Moves the evaluation of pinning to when it is needed, rather than doing it for every composite search. This both makes it more "pay for play" and enables more complex scenarios in the future by allowing the call sites to change behavior more easily.

Also fixes a few problems that I found along the way:

  1. CLICore reaching in to RepoCore rather than strictly using publics
  2. Move includes towards convention ("file" for files in the project, <file> for files outside of the project)
  3. Applies pins to the COM DefaultInstallVersion and IsUpdateAvailable properties
    • Because the caller can still see all available versions, they can choose to ignore the pinned properties

Validation

Existing regression tests.

Microsoft Reviewers: Open in CodeFlow

@JohnMcPMS JohnMcPMS requested a review from a team as a code owner February 7, 2024 19:27
florelis
florelis previously approved these changes Feb 7, 2024
}

// Gets a value indicating whether an available version is newer than the installed version.
virtual bool IsUpdateAvailable(PinBehavior pinBehavior) const = 0;
Copy link
Member

Choose a reason for hiding this comment

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

I'm guessing this is removed to move the work to the caller, who should consider pins?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct, it didn't seem right to leave this there to be misused. Additionally, it can't properly consider multiple installed versions, which is a major factor driving this change.

Comment on lines 83 to 84
// Determines if the given version is an update to the installed version that this object was created with.
bool IsUpdate(const std::shared_ptr<AppInstaller::Repository::IPackageVersion>& availableVersion);
Copy link
Member

Choose a reason for hiding this comment

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

Does this consider the pins?

Copy link
Member Author

Choose a reason for hiding this comment

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

It does not itself consider pins. It is just the new location for this method to try and force proper consideration of pins. An even larger change might be to create an entire "version selector" class that considers many variables before deciding on the most appropriate version to install.

Comment on lines 80 to 81
// Gets the latest available package that fits within the pinning restrictions.
std::shared_ptr<AppInstaller::Repository::IPackageVersion> GetLatestAvailableVersionForPins(const std::shared_ptr<AppInstaller::Repository::IPackage>& package);
Copy link
Member

Choose a reason for hiding this comment

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

Is the installed version in package used in any way? Do we have any expectations about it? (e.g., it is not set, or it matches what this object has)

Comment on lines 80 to 84
// Gets the latest available package that fits within the pinning restrictions.
std::shared_ptr<AppInstaller::Repository::IPackageVersion> GetLatestAvailableVersionForPins(const std::shared_ptr<AppInstaller::Repository::IPackage>& package);

// Determines if the given version is an update to the installed version that this object was created with.
bool IsUpdate(const std::shared_ptr<AppInstaller::Repository::IPackageVersion>& availableVersion);
Copy link
Member

Choose a reason for hiding this comment

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

These functions assume that the available version passed as parameters are for the same package as the installed version, right? If so, I'd mention that in a comment

std::shared_ptr<AppInstaller::Repository::Microsoft::PinningIndex> m_database;
std::optional<Pin> m_installedPin;
std::optional<Utility::VersionAndChannel> m_installedVersion;
std::map<PinKey, std::optional<Pin>> m_availablePins;
Copy link
Member

Choose a reason for hiding this comment

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

It took me a moment to get that this is only used as a cache for EvaluatePinType() and I had to look for all uses to make sure. May be worth adding a comment here to make it easier to understand.

return PinType::Unknown;
}

// Gets the pinned state for an available PackageVersionKey that may have a pin,
Copy link
Member

Choose a reason for hiding this comment

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

PackageVersionKey -> Version?

PortableIndex::PortableIndex(PortableIndex&&) = default;
PortableIndex& PortableIndex::operator=(PortableIndex&&) = default;

PortableIndex::~PortableIndex() = default;
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, is there particular reason we move these default constructor/destructor here where in other places we just define "= default" in header? Or this is the preferred convention in future?

Copy link
Member Author

Choose a reason for hiding this comment

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

It is part of pImpl; the destruction of the smart pointer has to happen in the compilation unit that has access to the destructor. Leaving it in the header requires that the caller can do that, but moving it to the .cpp moves that requirement to the implementation. This allows the IPortableIndex type to simply be a forward declaration for the public header and only a complete type in the .cpp.

This is not new convention, but application of a specific technique for this purpose.

@@ -29,6 +29,11 @@ namespace AppInstaller::Repository::Microsoft
return { filePath, disposition, std::move(indexFile) };
}

// Opens or creates a PinningIndex database on the default path.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: update comment

Copy link
Member Author

Choose a reason for hiding this comment

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

Will update the comment in my other change as soon as I merge them.

@JohnMcPMS JohnMcPMS merged commit 30e54e4 into microsoft:master Feb 8, 2024
8 checks passed
@JohnMcPMS JohnMcPMS deleted the move-pins branch February 8, 2024 16:50
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.

3 participants