microsoft / winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).
https://learn.microsoft.com/windows/package-manager/
MIT License
23.03k stars 1.43k forks source link

Error installing multiple packages in parallel using COM API #4587

Closed AmelBawa-msft closed 3 months ago

AmelBawa-msft commented 3 months ago

Brief description of your issue

From Dev Home, when calling the COM API during installation from multiple threads running in parallel, often an exception occurs for one of the calls.

Dev Home logs

System.Runtime.InteropServices.COMException (0x8007139F)
   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|39_0(Int32 hr)
   at ABI.Microsoft.Management.Deployment.ICatalogPackageMethods.get_DefaultInstallVersion(IObjectReference _obj)
   at Microsoft.Management.Deployment.CatalogPackage.get_DefaultInstallVersion()
   at DevHome.Services.WindowsPackageManager.Services.WinGetPackageInstaller.InstallPackageInternalAsync(CatalogPackage package, String version, Guid activityId)

AppInstaller logs

2024-06-26 10:00:53.540 [FAIL] C:\__w\1\s\external\pkg\src\AppInstallerRepositoryCore\Microsoft\SQLiteIndexSource.cpp(24)\WindowsPackageManager.dll!00007FFB8CE49D82: (caller: 00007FFB8CE7372E) Exception(2) tid(6288) 8007139F The group or resource is not in the correct state to perform the requested operation.

2024-06-26 10:00:53.541 [FAIL] WindowsPackageManager.dll!00007FFB8CF09106: ReturnHr(2) tid(6288) 8007139F The group or resource is not in the correct state to perform the requested operation.

    Msg:[C:\__w\1\s\external\pkg\src\AppInstallerRepositoryCore\Microsoft\SQLiteIndexSource.cpp(24)\WindowsPackageManager.dll!00007FFB8CE49D82: (caller: 00007FFB8CE7372E) Exception(2) tid(6288) 8007139F The group or resource is not in the correct state to perform the requested operation.

]

Steps to reproduce

From Dev Home, attempt to install:

Expected behavior

Ability to call the API from multiple threads

Actual behavior

At least one call will throw an exception (logs above)

Environment

Windows Package Manager (Preview) v1.9.1763-preview
Trenly commented 3 months ago

Correct me if I'm wrong, but isn’t this a limitation of MSI installers in general, where only one operation can be performed at a time anyways? Even with exe installers, although they can run at the same time if they attempt to access the same resource, there could be issues.

To me it seems that best practice for any automated installation is to only allow a single thread to process an install at any given time

JohnMcPMS commented 3 months ago

Correct me if I'm wrong, but isn’t this a limitation of MSI installers in general, where only one operation can be performed at a time anyways? Even with exe installers, although they can run at the same time if they attempt to access the same resource, there could be issues.

To me it seems that best practice for any automated installation is to only allow a single thread to process an install at any given time

We already take care of that in the COM server, doing the things that we can in parallel (downloads) and serializing the parts that we must (installs [except of MSIX, because it takes care of that]).

@amelbawa-msft was able to capture a TTT for me and I determined that it was an issue in winget caused by a lack of thread safety around our opening of the tracking catalog (really, around the shared_ptr where we store it). So ultimately the error occurs due to a race on searching using that source/catalog the first time.

https://github.com/microsoft/winget-cli/blob/015f0e9d9d6fd8d0d40e51dce264cd7744886c7b/src/AppInstallerRepositoryCore/RepositorySource.cpp#L986-L989