From 38bc7d36149060c3f7df09928fe70f36c2c36b0c Mon Sep 17 00:00:00 2001 From: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com> Date: Fri, 14 Jul 2023 17:19:25 -0700 Subject: [PATCH] Sync eng/common directory with azure-sdk-tools for PR 6521 (#21180) * Use System.Threading.Mutex to make threadsafe * Rename test, add comments --------- Co-authored-by: Mike Harder --- .../scripts/Helpers/PSModule-Helpers.ps1 | 71 ++++++++++++------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/eng/common/scripts/Helpers/PSModule-Helpers.ps1 b/eng/common/scripts/Helpers/PSModule-Helpers.ps1 index d9a5afaab1b3..bfca8a4154d8 100644 --- a/eng/common/scripts/Helpers/PSModule-Helpers.ps1 +++ b/eng/common/scripts/Helpers/PSModule-Helpers.ps1 @@ -47,6 +47,7 @@ function Update-PSModulePathForCI() } } +# Manual test at eng/common-tests/psmodule-helpers/Install-Module-Parallel.ps1 # If we want to use another default repository other then PSGallery we can update the default parameters function Install-ModuleIfNotInstalled() { @@ -65,35 +66,53 @@ function Install-ModuleIfNotInstalled() if ($modules.Count -eq 0) { - $repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl }) - if ($repositories.Count -eq 0) - { - Register-PSRepository -Name $repositoryUrl -SourceLocation $repositoryUrl -InstallationPolicy Trusted - $repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl }) - if ($repositories.Count -eq 0) { - Write-Error "Failed to registory package repository $repositoryUrl." - return + # Use double-checked locking to avoid locking when module is already installed + $mutex = New-Object System.Threading.Mutex($false, "Install-ModuleIfNotInstalled") + $null = $mutex.WaitOne() + + try { + # Check installed modules again after acquiring lock + $modules = (Get-Module -ListAvailable $moduleName) + if ($version -as [Version]) { + $modules = $modules.Where({ [Version]$_.Version -ge [Version]$version }) } - } - $repository = $repositories[0] - - if ($repository.InstallationPolicy -ne "Trusted") { - Set-PSRepository -Name $repository.Name -InstallationPolicy "Trusted" - } - Write-Host "Installing module $moduleName with min version $version from $repositoryUrl" - # Install under CurrentUser scope so that the end up under $CurrentUserModulePath for caching - Install-Module $moduleName -MinimumVersion $version -Repository $repository.Name -Scope CurrentUser -Force - - # Ensure module installed - $modules = (Get-Module -ListAvailable $moduleName) - if ($version -as [Version]) { - $modules = $modules.Where({ [Version]$_.Version -ge [Version]$version }) + if ($modules.Count -eq 0) + { + $repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl }) + if ($repositories.Count -eq 0) + { + Register-PSRepository -Name $repositoryUrl -SourceLocation $repositoryUrl -InstallationPolicy Trusted + $repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl }) + if ($repositories.Count -eq 0) { + Write-Error "Failed to register package repository $repositoryUrl." + return + } + } + $repository = $repositories[0] + + if ($repository.InstallationPolicy -ne "Trusted") { + Set-PSRepository -Name $repository.Name -InstallationPolicy "Trusted" + } + + Write-Host "Installing module $moduleName with min version $version from $repositoryUrl" + # Install under CurrentUser scope so that the end up under $CurrentUserModulePath for caching + Install-Module $moduleName -MinimumVersion $version -Repository $repository.Name -Scope CurrentUser -Force + + # Ensure module installed + $modules = (Get-Module -ListAvailable $moduleName) + if ($version -as [Version]) { + $modules = $modules.Where({ [Version]$_.Version -ge [Version]$version }) + } + + if ($modules.Count -eq 0) { + Write-Error "Failed to install module $moduleName with version $version" + return + } + } } - - if ($modules.Count -eq 0) { - Write-Error "Failed to install module $moduleName with version $version" - return + finally { + $mutex.ReleaseMutex() } }