Meu pensamento é estabelecer uma fila criando um arquivo de bloqueio por nova instância do seu script. Quando o script é executado, ele verifica um diretório dedicado ao rastreamento da fila para instâncias existentes do script. Se não houver nenhum, o script se adiciona à frente da fila, executa alguma ação (executa seu código) e, em seguida, limpa seu bloqueio. Se houver bloqueios, um novo será adicionado ao final da fila e a instância verificará incessantemente até que esteja na frente da fila.
Isso permite que você execute o mesmo script várias vezes, manipulando-se individualmente, verificando a fila disponível externamente.
Os arquivos de bloqueio são estruturados como Index, delimiter ("_"), ID do processo.
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
Abaixo está um exemplo fictício de linha do tempo no qual você fez o download de três arquivos (eu escolhi PIDs aleatórios).
- O arquivo 1 é baixado e inicia o script. Não há bloqueios existentes. Crie o bloqueio "0_19831". Estamos no topo da pilha, então seu código é executado. Este é um grande e-book, por isso o seu código de transferência de arquivos levará um minuto completo para ser executado.
- O arquivo 2 é baixado e inicia o script. Bloqueio (s) existem. Criar bloqueio "1_332". Não estamos no topo da pilha, por isso vamos esperar no nosso
do/until
e continuar a verificar até sermos os primeiros da fila. - Arquivo 1 terminou a cópia. Excluir bloqueio "0_19831".
- O arquivo 3 é baixado e inicia o script. Bloqueio (s) existem. Crie o bloqueio "2_7582". Não estamos no topo da pilha, espere até que estejamos.
- Arquivo 2 terminou de copiar. Excluir bloqueio "1_332".
- Arquivo 3 terminou de copiar. Excluir bloqueio "2_7582".
Esta solução não é à prova de balas, mas pode funcionar dependendo da escala.