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: Robson Alexandre
Subject: Re: [shell-script] Estrutura de script para criar fila de espera
Date: Wed, 30 Sep 2015 17:48:25 +0000

Boa tarde,

Ainda estamos discutindo detalhes do projeto, mas acredito que muito provavelmente:
1- O acessos dos usuários físicos será através de um sistema web já existente.
2- O acionamento (disparo) do script será remoto através de um usuário do sistema (web) via ssh ou cgi (com algum token).
3- Acionado o disparo do script, o acesso poderá ser encerrado sim, que a rotina deverá ficar em execução.
Como já dito, a solução em shell será suficiente apenas para atender o serviço dos cálculos (que demanda alto processamento e memória alocada), e informações de status, quantidade de processos executados, etc que ficarão disponíveis num formato JSON para consumo de outro sistema.

A solução pode parecer complexa, mas uma premissa é a segregação dos serviços, por isso o script shell foi escolhido para resolver o problema devido seu alto desempenho e tempo de resposta ao processamento necessário. De resto, outros serviços terão requisitos para a integração e terão que se adequar a necessidade.

Pensei em usar algum SGBD como sqlite realmente. Acredito que esta forma de persistência a informação fica melhor organizada.

Minha dúvida ainda é: qual seria a melhor forma de controlar/gerenciar esta fila de processos, se com named-pipe, ou como exemplificaram acima com signals e trap.
Pelo que pude entender o uso de named-pipe dispensa uma logística mais complexa como a usada trabalhando com signals e trap.

O uso de daemons, scripts na crontab e logs me parece boa idéia também.



Atenciosamente
Robson Alexandre

Em qua, 23 de set de 2015 às 11:23, Rafael Nery Brito address@hidden [shell-script] <address@hidden> escreveu:
 

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]