Enviado em 06/04/2012 - 06:49h
A Páscoa é um evento religioso cristão, normalmente considerado pelas igrejas ligadas a esta corrente religiosa como a maior e a mais importante festa da Cristandade. Na Páscoa os cristãos celebram a Ressurreição de Jesus Cristo depois da sua morte por crucificação que teria ocorrido nesta época do ano em 30 ou 33 da Era Comum. A Páscoa pode cair em uma data, entre 22 de março e 25 de abril. O termo pode referir-se também ao período do ano canônico que dura cerca de dois meses, desde o domingo de Páscoa até ao Pentecostes. Então exijo meus direitos kkkk. Quero todos os feriados. Antigamente os feriados de páscoa eram de 7 dias a 10 dias. Hoje a páscoa é apenas um evento comercial onde se gastar uma barbaridade.
#!/bin/bash
# file: bancao_loop.sh
# name: Processa contas para o DataWare.
# Author: #GaTux
# version: alfa 0.5
# more:
# objetives: Atualiza o perfil no bancão DataWare.
# ----------------------------------------------------------------------------#
# Observações:
# ------------
# parametro 1 - Trata origens e insere no DataWare.
# se vier "2" vai processar ( escalas globais )
# se vier "7" vai processar as rotinas (pontos/apostas)
# se vier "0" processa origens indeterminadas ou <> de 2 e 7.
# Se enquadram como 0 (ZERO) = manual, query manual, CTA, etc...
# parametro 2 - Recebe o número de canal que vai trabalhar.
# parametro 3 - Serve para saber se vamos ou não usar log extendido.
# Se (0 ou vazio) não fará o log.
# Se (1 indicará gravação de log extendido ref. update no DataWare)
# Este script deve estar em ...:
# www/degringolando/extensions/includes
# parametro 4 - Recebe a quantidade de segundos para fazer cada loop.
# Pode ser enviado centésimos de segundos, ex: 0.05
# Se parâmetro não for passado, assume default do script.
# ----------------------------------------------------------------------------#
# CHANGELOG: Versão alfa 0.5
# --------------------------
# - Correção de vários bugs de lógica nas funções.
# - Melhorias na diagramação das funções e estética.
# - Inclusão do parâmetro 5 para contagem de loops de tentativas.
# - Inluído o parâmetro 6 para gravar ou não LOG de trabalho.
# - Criado refresh especial para quando o LOCK for criado.
# - Iniciado documentação com vistas ao aprendizado da equipe.
# ----------------------------------------------------------------------------#
# CHANGELOG: Versão alfa 0.4
# --------------------------
# - Divido totalmente o script em funções onde foi possível.
# - Salva no log a gravação do arquivo exclusivo de trava. ***
# - Gravar quando retornar do php. ***
# - Salvar no log a gravação do arquivo exclusivo de trava. ***
# - Gravar quando retornar do php. ***
# - Criação de novos parâmetros opcionais.
# ----------------------------------------------------------------------------#
# CHANGELOG: Versão alfa 0.3
# --------------------------
# - Criar arquivo geral para registrar o momento que vai executar o php.
# - Registrar no arquivo geral o momento que retorna do php.
# - Tentar travar arquivo arq_lock colocando dentro o número do terminal.
# ----------------------------------------------------------------------------#
# CHANGELOG: Versão alfa 0.2
# --------------------------
# - Ampliado escopo de comandos.
# - Mudança dos testes em IFs e condições.
# - Melhorado documentação.
# ----------------------------------------------------------------------------#
# CHANGELOG: Versão alfa 0.1
# --------------------------
# - Criação básica do script para controle de locks.
# - Criação dos parametros 1,2 e 3.
# ----------------------------------------------------------------------------#
! [ "$1" ] && echo "OBRIGATÓRIO 1º parâm, origens do insere contas. " && exit
! [ "$2" ] && echo "OBRIGATÓRIO 2º param, Nº de canais.Não pode ser 0." && exit
if [ "$2" -le "0" ] ; then
echo "Número do canal tem que ser maior que 0 (zero), ABORTANDO !!!!"
exit
fi
# ----------------------------------------------------------------------------#
# Fazendo um teste múltiplo para saber se a origem deseja está inclusa.
# Se não estiver, vai abortar o script e seria legal gerar um log de erro.
# ----------------------------------------------------------------------------#
if ! [ "$1" -eq "7" -o "$1" -eq "2" -o "$1" -eq "0" ]; then
echo "LOG_ERRO: [*****] NÃO É UMA ORIGEM VÁLIDA: $1 "
exit
else
echo "INFO: A origem está correta $1 seguindo em frente"
fi
# ----------------------------------------------------------------------------#
# INICIALIZANDO variáveis com parâmetros ou definindo padrões genéricos.
# ----------------------------------------------------------------------------#
NUM_ORIGEM="$1" # Número das orgiens a processar.
NUM_CANAL="$2" # Número do canal e não pode ser ZERO.
LOG_EXTENDIDO=${3:-"0"} # Se não for informado vai assumir ZERO (0)
NUM_SEGUNDOS=${4:-"4.0"} #
CONT_LOOP_LOCK=${5:-"500"} # Valor total que o loop poderá rodar.
LOG_TMP=${6:-"1"} # 1 = ATIVA log de acompanhamento. 0 = desativa.
CHAVE_TEMP="0" # Variável que só será usada se log de
# acompanhamento ativo. $LOG_TMP="1"
MICRO_DELAY="0.00"$(date +"%N") # Micro paradas reguláveis. Veja também a função.
MIN_REFRESH="0.0"$(date +"%N") #Momento para conferir o REFRESH da gravação.
# ----------------------------------------------------------------------------#
# Futuramente precisa fazer uma construção diferente.
# ----------------------------------------------------------------------------#
pasta=$(cat ../../../degringolando/virtual.txt) # Não é a melhor forma de fazer.
# ----------------------------------------------------------------------------#
# Testa se o diretório virtual existe fisicamente.
# Caso não encontre, gravar log e ABORTAR !!!
# ----------------------------------------------------------------------------#
if [ ! -d "$pasta" ]; then
echo "Não achou arquivo para caminho virtual"
exit
fi
# ----------------------------------------------------------------------------#
# Arquivo de LOCK para uso do próprio canal.
# O mesmo número de canal só pode entrar no ar um por vez.
# A variável filename controla o nome deste arquivo.
# Quando a rotina for finalizada, deve apagar o arquivo de LOCK.
# ----------------------------------------------------------------------------#
filename=$pasta"/lock_contas_origem_"$NUM_ORIGEM"_canal_"$NUM_CANAL".txt"
# ----------------------------------------------------------------------------#
# Arquivo de TRAVA para parar o serviço que está em execução.
# Caso a rotina encontre este arquivo deve encerrar suas atividades.
# Além de parar o trabalho, precisa apagar o arquivo de LOCK.
# ----------------------------------------------------------------------------#
arqpara=$pasta"/para_contas_origem_"$NUM_ORIGEM"_canal_"$NUM_CANAL".txt"
# ----------------------------------------------------------------------------#
# Arquivo de uso exclusivo de uma determinada origem.
# Ele serve para gravar o número do canal para ter certeza se ele está em uso.
# ----------------------------------------------------------------------------#
ARQ_LOCK=$pasta"/lock_contas_"$NUM_ORIGEM"_exclusivo.txt"
# ----------------------------------------------------------------------------#
# Arquivo de log que grava entradas de processamentos de retorno até do php.
# ----------------------------------------------------------------------------#
ARQ_LOG=$pasta"/log_contas_"$NUM_ORIGEM".txt"
# ----------------------------------------------------------------------------#
###############################################################################
###############################################################################
##### Área destinada para FUNÇÕES. Variáveis globais todas devem estar acima.
###############################################################################
###############################################################################
#-----------------------------------------------------------------------------#
# INÍCIO >>> function microparadinhas()
# Foi melhor passar para uma função porque se for necessário alterar, vamos
# fazer em um lugar apenas. Outro motivo é com relação aos horários.
#-----------------------------------------------------------------------------#
function microparadinhas()
{
MICRO_DELAY="0.00"$(date +"%N")
sleep "$MICRO_DELAY" # Uma parada breve.
}
#-----------------------------------------------------------------------------#
#FIM >>> function microparadinhas() RETORNO: [NADA]
#-----------------------------------------------------------------------------#
# ----------------------------------------------------------------------------#
# INÍCIO: function move_log()
# Objetivo: Verificar se o tamanho do log está muito grande.
# Se estiver, vai move-lo com a data e hora.
# ----------------------------------------------------------------------------#
function move_log()
{
: # Em desenvolvimento. Tem que se estudar uma estratégia para não
# ficar verificando a cada momento. Pelo menos 3 horas.
# Estratégia: Gravar um arquivo com a data, hora tamanho do arquivo.
# Verificar o arquivo já gravado para fazer o cálculo
# de tempo e com base na média dos outros
# mover o arquivo.
}
#-----------------------------------------------------------------------------#
#FIM >>> function microparadinhas() RETORNO: [NADA]
#-----------------------------------------------------------------------------#
# ----------------------------------------------------------------------------#
# INÍCIO: function log_opera()
# ----------------------------------------------------------------------------#
function log_opera()
{
# Recebe ATÉ 2 parâmetroS para gravar o passo do log.
# PARAM: 1 - Tipo de atividade sendo executada.
# PARAM: 2 - (OPCIONAL) MICRO_DELAY especial de gravação.
local atividade_log meu_log
atividade_log="$1"
MICRO_DELAY=${2:-"$MICRO_DELAY"} # força no caso da gravação inicial.
meu_log="[Chave Temp: $CHAVE_TEMP] §
[$atividade_log] §
[Orgiem.: "$NUM_ORIGEM"] §
[Nº do Canal: "$NUM_CANAL"] §
[Horário: "$(date +"%T:%N")"] §
[PID: "$$"] §
[Microparada: "$MICRO_DELAY"] §
[Sleep segundos: "$NUM_SEGUNDOS"]"
echo $meu_log >> $ARQ_LOG
}
# ----------------------------------------------------------------------------#
# INÍCIO: function insere_contas_php()
# Vai realizar a gravação do processamento executando o PHP.
# Só pode ter chegado até aqui se tudo foi testado antes.
# Mesmo assim, vamos fazer mais um teste para não correr risco.
# ----------------------------------------------------------------------------#
function insere_contas_php()
{
local ver_retorno
# RECEBE: Nome do arquivo de trava exclusiva.
ver_retorno="$1"
if [ "$LOG_TMP" = "1" ]; then
if [ "$ver_retorno" = "$ARQ_LOCK" ]; then
log_opera "ENTRANDO..:"
else
log_opera "FALHA-CN..:"
fi
fi
#-----------------------------------------------------------------#
# Processa o código PHP.
# Recebe alguns tipos de retornos do código PHP.
#-----------------------------------------------------------------#
retorno_php=$(php -f task_dataware.php $NUM_ORIGEM $LOG_EXTENDIDO $NUM_CANAL)
if [ "$LOG_TMP" = "1" ]; then
log_opera "RETORNANDO:" # Gravando o log.
fi
#-----------------------------------------------------------------#
# Verificando o que veio no retorno.
# A variável abaixo está sendo criada com as 4 primeiras posições.
#-----------------------------------------------------------------#
erro_script=$(echo "$retorno_php" | cut -c-4)
if [ "$erro_script" = "ERRO" ]; then
#-------------------------------------------------------------#
# Se entrou aqui é porque a string contém a palavra ERRO.
# O script não pode continuar e o serviço será cancelado.
#-------------------------------------------------------------#
if [ "$LOG_TMP" = "1" ]; then
log_opera "ERRO---PHP:" # Gravando o log.
fi
rm "$filename" # Apagando o arquivo do canal.
fi
}
#-----------------------------------------------------------------------------#
#FIM >>> function insere_contas_php()
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# INÍCIO >>> function cria_lock()
# Função que vai APENAS criar o arquivo exclusivo de LOCK.
# Ela não testa se já existe, apenas cria.
# Caso algum problema exista na hora da criação, retornará erro 1.
# Este ponto é perigosão kkkkk
#-----------------------------------------------------------------------------#
function cria_lock()
{
local confere_erro
echo "$NUM_CANAL" > "$ARQ_LOCK"
confere_erro="$?" # Verifica se houve erro neste momento.
sleep "$MIN_REFRESH" # Refresh especial após a gravação do arquivo.
log_opera "CRIA--LOCK:" "$MIN_REFRESH" # Grava a criação original pela 1ª vez.
if [ "$confere_erro" -gt "0" ]; then
log_opera "ERRO-FATAL-CRIAÇÃO:" # Erro fatal na hora da criação.
return 1 # Aviso de erro.
fi
}
#-----------------------------------------------------------------------------#
#FIM >>> function cria_lock() RETORNO: NENHUM
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# INÍCIO >>> function testando_lock()
# Vamos fazer um loop tentando verificar o momento em que o arquivo não existe
# Quando ele conseguir, vai chamar a criação imediatamente.
# Se estourar o número de interações, retornará sem sucesso.
#-----------------------------------------------------------------------------#
function testando_lock()
{
local cont_rodando arquivo_de_lock cn_lock
while true ; do
if [ -f "$ARQ_LOCK" ]; then
#Contador para saber quantas vezes ele tentou.
cont_rodando=$((cont_rodando+1))
if [ "$cont_rodando" -gt "$CONT_LOOP_LOCK" ]; then
# Se o contador for maior que o limite vai sair.
arquivo_de_lock="FALHA"
break
fi
else
cria_lock # Criando o arquivo de lock
microparadinhas # Pequena espera para dar o refresh.
cn_lock=$(cat "$ARQ_LOCK") #Este momento é chave no processo.
if [ "$cn_lock" -eq "$NUM_CANAL" ]; then
arquivo_de_lock="$ARQ_LOCK"
break
else
arquivo_de_lock="FALHA CANAL"
break
fi
fi
done
echo $arquivo_de_lock # Retorna o nome do arquivo de lock ou FALHA.
}
#-----------------------------------------------------------------------------#
#FIM >>> function testando_lock() RETORNA: ####################################
# [FALHA] caso não consiga criar o arquivo exclusivo.
# ou
# Nome do arquivo de trava se estiver correto.
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# INÍCIO >>> function sleeps()
#-----------------------------------------------------------------------------#
function sleeps()
{
# ------------------------------------------------------------------------#
# Caso a origem seja 0 (zero), contém processamentos de
# contas pedidas manualmente, query manual, cta ou outras.
# Não há necessidade de dar tanta prioridade. Então podemos fazer um tempo
# diferente para elas.
# ------------------------------------------------------------------------#
if [ "$NUM_ORIGEM" = "0" ]
then
echo " Está aguardando 1 minuto porque a origem é 0 zero "
sleep 1m # Vai ficar parado 1 minuto. Pode virar parâmetro de uso.
fi
# ------------------------------------------------------------------------#
# Processamento da origem 2 (tem prioridade máxima)
# Por este motivo, vai ter um controle de tempo diferenciado de intervalo.
# ------------------------------------------------------------------------#
if [ "$NUM_ORIGEM" = "2" ]
then
microparadinhas # Vai executar uma micro parada....
fi
# ------------------------------------------------------------------------#
# Processamento da origem 7 pode trabalhar com tempo diferente.
# Na verdade estou fazendo assim só para ter uma idéia do que podemos fazer
# ------------------------------------------------------------------------#
if [ "$NUM_ORIGEM" = "7" ]
then
sleep "$NUM_SEGUNDOS" # Pega o que veio no parâmetro ou default.
fi
}
#-----------------------------------------------------------------------------#
#FIM >>> function sleeps()
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# INÍCIO >>> function stop_trabalho()
# Comanda a parada total dos trabalhos que estão sendo realizados.
#-----------------------------------------------------------------------------#
function stop_trabalho()
{
if [ -f "$arqpara" ]; then
#---------------------------------------------------------------------#
# Já que o arquivo de TRAVA foi encontrado, vamos abortar o trabalho.
# Antes é necessário apagar o arquivo de TRAVA.
# É uma operação perigosa porque podemos não ter permissões.
#---------------------------------------------------------------------#
log_opera "TRAVA-ATIVADA:" # Verificou o arquivo de trava e encerrou.
rm "$arqpara"
rm "$filename"
exit
fi
}
#-----------------------------------------------------------------------------#
#FIM >>> function stop_trabalho()
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# INÍCIO >>> function conf_falha()
# Faz não apenas a conferência de falhas, mas grava o trabalho.
#-----------------------------------------------------------------------------#
function conf_falha()
{
local local_retorno
# RECEBE: O nome do arquivo de LOCK exclusivo ou a palavra FALHA e derivados.
local_retorno="$1" #
if [ "$local_retorno" = "FALHA" ]; then
# Não conseguiu travar e vai tentar mais tarde.
microparadinhas # Vai executar uma micro parada....
echo "FALHA"
else
if [ "$local_retorno" = "$ARQ_LOCK" ]; then
#-----------------------------------------------------------------#
# Aparentemente, o retorno não foi de falha.
# Mesmo assim, precisamos ter certeza na hora da execução.
# Se o local_retorno possuir o nome correto, tudo está bem.
#-----------------------------------------------------------------#
insere_contas_php "$local_retorno" # Tenta processar.
microparadinhas # Vai executar uma micro parada....
echo "$local_retorno"
else
#-----------------------------------------------------------------#
# Não conseguiu confirmar o nome corretamente.
# Com certeza tem algo errado. Nada vamos fazer.
#-----------------------------------------------------------------#
microparadinhas # Vai executar uma micro parada....
echo "FALHA"
fi
fi
}
#-----------------------------------------------------------------------------#
#FIM >>> function conf_falha()
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# INÍCIO >>> function check_all()
# Faz uma verificação de todos processos delegando trabalho.
# Na verdade esta função só serve para eliminar repetições.
#-----------------------------------------------------------------------------#
function check_all()
{
local tem_retorno executando
tem_retorno=$(testando_lock) # Tenta capturar o retorno.
echo $tem_retorno
microparadinhas # Vai executar uma micro parada....
executando=$(conf_falha "$tem_retorno")
echo "$executando"
}
#-----------------------------------------------------------------------------#
#FIM >>> function check_all()
#-----------------------------------------------------------------------------#
###############################################################################
###############################################################################
##### FIM da Área destina para as FUNÇÕES.
###############################################################################
###############################################################################
# ----------------------------------------------------------------------------#
# Vamos testar se o arquivo existe.
# Caso já exista, não podemos trabalhar porque outro terminal pode estar
# usando e deve sair do script sem alterar nada.
# Como os scripts são chamados no cron, é muito provável que ele tente
# executar novamente este script com este canal.
# Com esta proteção, isto não irá acontecer.
# ----------------------------------------------------------------------------#
###############################################################################
###############################################################################
################ ÁREA DE TESTES PARCIAIS ######################################
###############################################################################
###############################################################################
###############################################################################
###############################################################################
################ FIM ÁREA DE TESTES ###########################################
###############################################################################
###############################################################################
if [ -f "$filename" ]; then
echo "O arquivo do canal já existe [ $filename ], operação será finalizada "
exit # Encontrou o arquivo do canal e vamos finalizar o script.
else
echo "Criando arquivo LOCK do canal em: $filename "
touch "$filename"
microparadinhas # Vai executar uma micro parada....
fi
# ----------------------------------------------------------------------------#
# Vamos ficar rodando este script indefinidamente até que alguém mande parar.
# Geralmente será finalizado se encontrar o arquivo de TRAVA.
# ----------------------------------------------------------------------------#
zeroide="0" # Uma boquetagem sem tamanho para contornar o contador.
while true ; do
microparadinhas # Vai executar uma micro parada....
sleeps # Processa os tempos de paradas necessários....
stop_trabalho # Faz o teste para saber se foi solicitado a interrupção.
if [ "$zeroide" = "0" ]; then
CHAVE_TEMP=$((CHAVE_TEMP+1)) #Contador meia boca de processamentos....
fi
# ------------------------------------------------------------------------#
# Testa se o arquivo de LOCK exclusivo existe ou não.
# Se existir, deve entrar em um processo para conseguir obter acesso.
# Se obter acesso, vai fazer testes e processar as rotinas.
# ------------------------------------------------------------------------#
if [ -f "$ARQ_LOCK" ]; then
#-----------------------------------------------------------------#
# O arquivo do canal está criado, então não há nada ser feito.
# Vamos dar um tempinho e retornar ao início do while.
#-----------------------------------------------------------------#
echo "Tentando travar o arquivo. Já rodou ......: $i "
check_all # Faz todas verificações e delega gravação.
zeroide="1" # Uma boquetagem sem tamanho para contornar o contador.
continue
else
check_all # Faz todas verificações e delega gravação.
zeroide="0" # Uma boquetagem sem tamanho para contornar o contador.
continue
fi
i=$((i+1)) #Contador meia boca para saber os loops e processamentos....
echo "Já RODOU $i vezes...."
done
# ----------------------------------------------------------------------------#
# Se saímos do while é porque o script está sendo finalizado.
# É necessário apagar o arquivo de LOCK antes de finalizar a operação.
# ----------------------------------------------------------------------------#
echo " Apagando o arquivo LOCK $filename antes de sair do script. "
rm "$filename"
exit 0
# ----------------------------------------------------------------------------#
# FIM
# ----------------------------------------------------------------------------#
# PENDÊNCIAS:
# Adicionar uma função genérica de log.
# Quando estiver pronto será só adicionar no local onde desejar.
# Falta testar com mais de 300 máquinas ao mesmo tempo.
# Aliviar o estress das queries duplicadas.
# Acompanhar médias de arquivos em pastas para ver se consegue melhorar
# a velocidade dos processos.
# ----------------------------------------------------------------------------#
#ERRO Informar parâmetro 1, origem ';
#ERRO Informar parâmetro 2, canal ';
#ERRO Informar falha na trava ';