Динамическое добавление задач в очередь заданий PowerShell

Я создал скрипт PowerShell, который копирует любые электронные книги, которые я загружаю в заданный каталог, который периодически сканируется моим менеджером электронных книг и добавляется в мою библиотеку. Скрипт запускается сразу после каждой загрузки.

проблема в том, что, когда несколько книг загружаются одновременно или примерно в то же время, менеджер электронных книг блокируется и перестает отвечать на запросы.

поэтому я хотел бы поставить копирование в очередь с помощью PowerShell заданий, но я не знаю, как создать одну очередь (один параллелизм), чтобы каждое последующее задание ожидало завершения каждого более старого задания.

то есть, я хотел бы, чтобы скрипт создал задание (назовем его "задание книги"), которое периодически проверяет очередь выполняемых заданий книги, чтобы увидеть, завершились ли все старые задания книги до его выполнения. По завершении задания книги следует объявить, что оно завершилось, что может быть обнаружено более молодыми заданиями книги.

тут кто-нибудь знает как я могу это сделать? Я видел подобный вопрос здесь, что я смотрю на: фоновые задачи в PowerShell, однако, в моем случае я запускаю скрипт несколько раз (после каждой новой загрузки).

14
задан Mavaddat Javid
08.02.2023 13:37 Количество просмотров материала 3448
Распечатать страницу

1 ответ

моя мысль состоит в том, чтобы создать очередь, создав один файл блокировки на новый экземпляр вашего сценария. При выполнении сценария проверяется каталог, предназначенный для отслеживания очереди на наличие существующих экземпляров сценария. Если их нет, скрипт добавляет себя в начало очереди, выполняет какое-то действие (запускает ваш код), затем очищает свою блокировку. Если есть замки, новый будет добавлен в конец очереди, и экземпляр будет бесконечно, пока она в передней части очередь.

это позволяет запускать один и тот же сценарий несколько раз, каждый по отдельности обрабатывая себя, проверяя внешнюю доступную очередь.

файлы блокировки структурированы как индекс, разделитель ("_"), идентификатор процесса.

Clear-Host

function New-Lock ([int] $index) {
    $newLock = "$index" + "_" + $pid + ".lck"
    New-Item $queue$newLock | Out-Null
}

$queue = "C:\locks\"

# find the end of the stack
$locks = gci $queue *.lck | sort | select -expandproperty name

# if locks exist, find the end of the stack by selecting the index of the last lock
if($locks) {
    # gets the last lock file, selects the index by splitting on the delimiter
    [int]$last = [convert]::ToInt32(($locks | select -last 1).Split("_")[0],10)

    # add the lock to the end of the stack
    New-Lock ($last + 1)
}
# if no locks exist, create one at the top of the stack
else {
    New-Lock 0
}

# check if we're at the top of the stack
do {
    $locks = gci $queue *.lck | sort | select -expandproperty name

    # this is the PID on the top of the stack
    [int]$top = [convert]::ToInt32(($locks | select -first 1).Split("_")[1].Split(".")[0],10)
    write-verbose "not at the top..."
    sleep 1
} until ($pid -eq $top)

# if we're here, we've been to the top. it's our turn to do something
Write-Verbose "we've reached the top!"
# <do something. put your code here>
# might be good to add some Start-Sleep here
# </do something put your code here>

# now that we're done, let's delete our lock
gci $queue | select -first 1 | Remove-Item

Ниже приведен вымышленный пример временной шкалы, в котором вы загрузили три файла (я выбрал случайные PIDs).

  • файл 1 загружается и запускает скрипт. Не существует замков. Создать блокировку "0_19831". Мы находимся в верхней части стека, поэтому ваш код выполняется. Это большая электронная книга, поэтому ваш код передачи файлов займет полную минуту.
  • файл 2 загружается и запускает скрипт. Замок(ы) существуют. Создать замок "1_332". Мы не на вершине стека, так что будем ждать в нашем do/until и продолжайте проверять, пока мы не первые в очереди.
  • файл 1 копирование завершено. Удалить замок "0_19831".
  • файл 3 загружается и запускает скрипт. Замок(с) существовать. Создать замок "2_7582". Мы не в верхней части стека, подождите, пока мы.
  • копирование файла 2 завершено. Удалить замок "1_332".
  • копирование файла 3 завершено. Удалить замок "2_7582".

это решение не пуленепробиваемые, но может работать в зависимости от масштаба.

3
отвечен root 2023-02-09 21:25

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх