Moim pomysłem jest ustanowienie kolejki poprzez utworzenie jednego pliku blokady na nowe wystąpienie skryptu. Po uruchomieniu skryptu sprawdza katalog poświęcony śledzeniu kolejki dla istniejących instancji skryptu. Jeśli ich nie ma, skrypt dodaje się na początku kolejki, wykonuje akcję (uruchamia kod), a następnie czyści blokadę. Jeśli są blokady, nowa zostanie dodana na końcu kolejki, a instancja będzie bez końca sprawdzać, aż znajdzie się na początku kolejki.
Pozwala to na uruchomienie tego samego skryptu wiele razy, a każdy z nich sam sobie radzi, sprawdzając dostępną zewnętrznie kolejkę.
Pliki blokady mają strukturę indeksu, separatora („_”), identyfikatora procesu.
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
Poniżej znajduje się fikcyjny przykład na osi czasu, w którym pobrałeś trzy pliki (wybrałem losowe PID).
- Plik 1 zostanie pobrany i uruchomi skrypt. Brak istniejących zamków. Utwórz blokadę „0_19831”. Jesteśmy na szczycie stosu, więc Twój kod jest wykonywany. To duży e-book, więc uruchomienie kodu transferu pliku zajmie pełną minutę.
- Plik 2 zostanie pobrany i uruchomi skrypt. Istnieją blokady. Utwórz blokadę „1_332”. Nie znajdujemy się na szczycie stosu, więc poczekamy na siebie
do/until
i sprawdzimy, aż do pierwszego szeregu.
- Plik 1 zakończył kopiowanie. Usuń blokadę „0_19831”.
- Plik 3 zostanie pobrany i uruchomi skrypt. Istnieją blokady. Utwórz blokadę „2_7582”. Nie jesteśmy na szczycie stosu, poczekaj, aż będziemy.
- Plik 2 zakończył kopiowanie. Usuń blokadę „1_332”.
- Plik 3 zakończył kopiowanie. Usuń blokadę „2_7582”.
To rozwiązanie nie jest kuloodporne, ale może działać w zależności od skali.