Как установить модуль Powershell одновременно? - PullRequest
1 голос
/ 15 мая 2019

У меня есть сборка проверки Pull Request для разных ветвей, то есть несколько одновременных экземпляров сборки - очень распространенная вещь.

Одна из вещей, которую делает сборка, - это установка модуля. Теперь я могу изменить профиль агента сборки и установить модуль оттуда, но я хочу избежать дополнительной настройки агента сборки. Итак, моя сборка устанавливает модуль в текущей области пользователя.

Я заметил, что Install-Module не кажется безопасным при одновременном вызове - он может не работать со всеми видами различных и странных сообщений об ошибках.

Теперь я решил эту проблему с помощью именованного мьютекса, полученного до и выпущенного после, но это вызывает ужасную производительность - код иногда ждет 30 секунд и более. Итак, как решить эту проблему? Как установить модуль powershell одновременно, но безопасно и с хорошей производительностью?

РЕДАКТИРОВАТЬ 1

Это расстраивает. Я пытаюсь отследить одновременную установку, используя Set-PSDebug -Trace 2, но, очевидно, Install-Module имеет много вызовов Write-Debug, вызывающих функции, которые сами по себе небезопасны для одновременного выполнения! Поэтому попытка отследить на самом деле ухудшает положение.

1 Ответ

0 голосов
/ 17 мая 2019

Очевидно, Install-Module - это полностью НЕ БЕЗОПАСНО для запуска во время сборки, когда несколько сборок выполняются на одном и том же агенте. Похоже, использование названного Mutex - самый безопасный подход.

РЕДАКТИРОВАТЬ 1

В многопоточных средах вызов следующих команд небезопасен без явного мьютекса:

  • Install-Module
  • Import-Module
  • Get-PSRepository без аргументов

Может быть, больше. В своем коде я вызываю все три команды и обнаружил, что все они вместе должны находиться в одном мьютексе, то есть эти комбинации не работают:

Не работает # 1

$mtx.WaitOne()
try
{
    Install-Module ...
}
finally
{
    $mtx.ReleaseMutex()
}
Import-Module ...
Get-PSRepository ...

Не работает # 2

$mtx.WaitOne()
try
{
    Install-Module ...
    Import-Module ...
}
finally
{
    $mtx.ReleaseMutex()
}
Get-PSRepository

Похоже, что единственная безопасная опция:

$mtx.WaitOne()
try
{
    Install-Module ...
    Import-Module ...
    Get-PSRepository
}
finally
{
    $mtx.ReleaseMutex()
}

Что удивительно, потому что я не ожидаю, что Install-Module или Import-Module повлияет на Get-PSRepository, но каким-то образом они влияют:

   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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...