shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Estrutura de script para criar fila de espera


From: Rafael Nery Brito
Subject: Re: [shell-script] Estrutura de script para criar fila de espera
Date: Tue, 22 Sep 2015 15:49:55 -0300

Robson, fiz um script certa vez que lidava com fila de espera para geração de imagens usando um código PHP, mas sem depender do próprio script rodar diretamente o próximo script. (Espero ter entendido sua pergunta)

A solução que dei foi agendar o script pela cron de minuto em minuto (*) e o script em execução manter um arquivo .lock enquanto estivesse em execução, contendo o PID do próprio script para futura referência. Quando o script fosse executado, então ele verificava a presença do arquivo lock, e se já existisse, ele colocaria um arquivo lockwait, dizendo que ele aguarda na fila de execução, e fica testando a cada poucos segundos se o arquivo .lock ainda existe. O script rodando apagará o arquivo lock ao final, liberando o outro script que já aguardava, que então renomeia o próprio arquivo .lockwait para .lock (para não existir um vão de tempo sem nenhum dos arquivos lock na pasta). Então começa a processar a fila de arquivos.
Caso o script encontre um arquivo lockwait, ele deve encerrar sem fazer nada pois já há dois scripts rodando de disparos anteriores da cron.
Vc pode ir ajustando o tempo do agendamento na cron para que o script não precise ficar esperando o próximo terminar, ainda que isso não gaste tanto recurso pois serão no máximo dois scripts, um trabalhando e outro esperando (fora o terceiro que poderá rodar e encerrar qdo detectar os outros dois arquivos lock).
Desse jeito, criei um script que pode tratar a fila de arquivos em intervalos até menores que um minuto, para não deixar muitos arquivos na espera.

Se sua demanda não for tão intensa quanto a minha na época do script, não implemente a parte do lockwait, aí vc sempre terá um script tentando tratar a fila a cada disparo da cron.

Eu também tinha que considerar que meu script não poderia rodar em paralelo ao próximo a ser disparado pela cron por ser uma tarefa que demandava muito do meu servidor e em paralelo, só iriam acumular scripts rodando processos mais lentos e que deixava os outros mais lentos. Caso seu problema possa ser tratado em paralelo por várias instâncias do script em paralelo, sugiro que ao tratar os arquivos da fila,  antes de tratar cada arquivo, vc o renomeie adicionando uma extensão ou padrão diferente (por exemplo, .emUso) do que o script procura na pasta da fila, senão dois scripts podem tentar tratar o mesmo arquivo.

Outro esquema útil na época era usar o arquivo lock para parar o tratamento da fila sem mexer na cron.

Seria interessante, para vc poder ajustar o tempo na cron, que vc criasse um log de execução do script, simplesmente gravando data, hora, pid, se foi iniciado direto, se ficou aguardando, se saiu por ja existirem os dois locks, e caso o script chegue ao ponto de tratamento da fila de arquivos, grave no log o momento em que ele terminou e quantos arquivos tratou nesta execução.

Lembrando também que os arquivos na fila deveriam ser nomeados com data-hora antes do nome desejado para serem listados na ordem de entrada da fila, sem depender da data do próprio arquivo.

Acho que é isso (tudo).

Em 17/09/2015 11:29 AM, "Robson Alexandre address@hidden [shell-script]" <address@hidden> escreveu:


Bom dia a todos,

gostaria de saber a opinião dos colegas da lista e inclusive sugestões para seguinte demanda que estou a decidir qual a melhor maneira de se fazer.

Uma rotina que é disparada por um usuário qualquer e caso esta rotina já esteja em execução, cria-se uma fila de espera q é executada imediatamente após o término da anterior.

Bom, parece simples, é só colocar o script da rotina para chamar o próximo caso haja fila de espera, mas qual seria a melhor forma de realizar esse script?

Pensei em algo do tipo

cat <<EOF > script

#!/bin/bash
dir=/caminho/app

ps -C $0 || {
echo Executando rotina...
sleep 20  #simulando tempo de execução da rotina

queue=( $(wc -l $dir/queue) )
[ ${queue[0]} -gt 0 ] && at now + 1 minutes <<< "$(sed '1!d' $dir/queue; sed -i '1d' $dir/queue)"
} && {
echo $0 $* >> $dir/queue
}
EOF

cat <<EOF > queue
/caminho/app/script param1 param2 paramN
/caminho/app/script paramY paramX paramN
/caminho/app/script parama paramb paramN

EOF

Gostaria de opiniões e sugestões sobre desde o método para verificar se a rotina já está em execução (ps -C $0), até o uso do at para agendar o próximo da fila.
Alguém já fez algo parecido? Já tem alguma coisa implementada?

Atenciosamente
Robson Alexandre




reply via email to

[Prev in Thread] Current Thread [Next in Thread]