I have a Pull Request validation build running for different branches, ie several concurrent instances of the build is a very common thing.
One of the things the build does is install a module. Now I could modify the profile on the build agent and install module from there, but I want to avoid any extra build agent configuration. So, my build installs a module in the current user scope.
I noticed that Install-Module
does not seem to be safe when invoked concurrently - it may fail with all kinds of different and weird error messages.
Now I solved this with a named mutex acquired before and released after, but this causes abysmal performance - the code sometimes waits for 30 seconds and more. So, how to solve this problem? How to install a powershell module concurrently, but safely and with good performance?
EDIT 1
It is frustrating. I am trying to trace the concurrent installs using Set-PSDebug -Trace 2
, but apparently Install-Module
has a lot of Write-Debug
invocations calling to functions which are themselves not safe for concurrent execution! So trying to trace actually worsens matters.
Apparently, Install-Module
is totally NOT SAFE to run during a build where multiple builds run on the same agent. Looks like using a named Mutex is the safest approach.
EDIT 1
In a multi-threading environments invoking the following commands is not safe without explicit mutex:
Install-Module
Import-Module
Get-PSRepository
without arguments Maybe more. In my code I invoke all the three commands, and I discovered that all of them together must be in the same mutex, ie these combinations do not work:
Not working #1
$mtx.WaitOne()
try
{
Install-Module ...
}
finally
{
$mtx.ReleaseMutex()
}
Import-Module ...
Get-PSRepository ...
Not working #2
$mtx.WaitOne()
try
{
Install-Module ...
Import-Module ...
}
finally
{
$mtx.ReleaseMutex()
}
Get-PSRepository
The only safe option appears to be this one:
$mtx.WaitOne()
try
{
Install-Module ...
Import-Module ...
Get-PSRepository
}
finally
{
$mtx.ReleaseMutex()
}
Which is surprising, because I do not expect Install-Module
or Import-Module
to affect Get-PSRepository
, yet somehow they do:
ParameterBindingException: A parameter cannot be found that matches parameter name 'Provider'.
at Get-PSRepository<Process>, C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1: line 4496
at Use-ModuleFB22C60E, C:\Users\mkharitonov\AppData\Local\Temp\fb22c60e-a0c5-48b3-953a-0b580c6a2f5e\m_deadbeef_.ps1: line 167
at <ScriptBlock>, <No file>: line 4
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.