Dicas valiosas de programação – Parte 04

Introdução

Continuando o assunto de dicas valiosas de programação, vamos abordar alguns assuntos relacionados a JOBS (Programas sem interface), pontos de atenção, alternativas de controle, etc.

Considerações sobre JOBS

Em tópicos anteriores, vimos que existem várias formas de subir um ou mais jobs em um serviço do Protheus Server. A maior dificuldade dos JOBS consiste em saber o que ele está fazendo, e como ele está fazendo. O fato do Job não ter nenhum tipo de interface torna esse trabalho um pouco diferente dos demais programas.

Quando usamos um pool de JOBS, como por exemplo os processos de WebServices ou de portais WEB (JOB TYPE=WEBEX), definimos o número inicial (mínimo) de processos, numero máximo, e opcionalmente mínimo livre e incremento. Logo, não precisamos nos preocupar se o servidor recebe mais uma requisição e todos os processos que estão no ar estão ocupados — se o número máximo de processos configurado não foi atingido, o próprio Protheus Server coloca um ou mais jobs no ar.

Gerando LOG de um JOB

Normalmente quando precisamos acompanhar o que um determinado JOB está fazendo, podemos usar o IDE e/ou TDS para depurar o Job, ou caso isto não seja uma alternativa para a questão, o programa pode ser alterado para emitir mensagens a cada etapa de processamento. Uma das alternativas normalmente usadas — e mais simples de usar — é usar a função AdvPL conout() nos programas envolvidos, para registar no log de console do Protheus Server mensagens sobre o que cada processo está fazendo. Para diferenciar os processos, podemos usar a função ThreadID() do AdvPL, para identificar o número da thread que gerou a mensagem.

Outra alternativa interessante, inclusive mais interessante que usar o log de console do servidor de aplicação, é fazer com que o job crie um arquivo de LOG dele próprio em disco, usando por exemplo a função fCreate(), criando o arquivo em uma pasta a partir do RootPath do ambiente, usando por exemplo um prefixo mais o numero da thread atual mais o horário de inicio do job como nome do arquivo — para ficar fácil saber quais logs são de quais JOBS — e gravar os dados de LOG dentro desse arquivo usando a função fWrite()  — lembrando de inclusive gravar os caracteres chr(13)+chr(10) ao final de cada linha — estes caracteres de controle indicam uma quebra de linha em um arquivo no padrão Windows. Para Linux, a quebra de linha padrão é apenas chr(10).

Acompanhando a execução de um JOB

Quando você cria um determinado JOB para alguma tarefa longa, pode ser interessante saber em que ponto ou etapa da tarefa o JOB está trabalhando em um determinado momento. A solução mais leve, é você criar um nome de uma variável global — aquelas que são acessadas através das funções PutGlbVars() e GetGlbVars() — e alimentar dentro do JOB a variável global com a etapa atual do processo, enquanto um outro programa (em outro processo, com interface por exemplo) consulta a variável para saber qual é a tarefa interna do Job em andamento.

Desta forma, um programa externo pode consultar — através de variáveis globais com nomes pré-definidos — o status de não apenas um, mas vários jobs sendo executados no servidor de aplicação atual. Basta criar identificadores únicos não repetidos antes de iniciar os processos.

Ocorrências de Erro Críticas

Mesmo que o seu JOB possua um tratamento de erro, cercado com BEGIN SEQUENCE … END SEQUENCE e afins, as ocorrências de erro de criticidade mais alta não são interceptadas ou tratadas. Desse modo, se você apenas consulta uma variável global para pegar o status de um Job, ele pode ter sido derrubado ou ter finalizado com uma ocorrência critica de erro, e o programa que está esperando ou dependendo de um retorno dele nem sabe que ele já não está mais sendo executado.

Não há contorno para tentar manter no ar um JOB que foi finalizado por uma ocorrência crítica, porém você pode descobrir se ele ainda está no ar ou não, usando alguns recursos, por exemplo:

  1. Além da variável global para troca de status, faça o JOB obter por exemplo um Lock Virtual no DBAccess ou um Lock em Disco — busque no blog por “MUTEX” e veja algumas alternativas. A ideia é usar um recurso nomeado em modo exclusivo, que é liberado automaticamente caso o JOB seja finalizado por qualquer razão. Se o seu programa que espera retorno do JOB está sem receber nenhuma atualização, verifique se o JOB está no ar tentando fazer um bloqueio do recurso que o JOB está usando. Se o seu processo conseguiu o bloqueio, o JOB foi pro vinagre…
  2. Verifique se o seu processo ainda está no ar usando — com moderação — por exemplo a função GetUserInfoArray() — ela retorna um array com as informações dos processos em execução na instância atual do Protheus Server. Para isso, pode ser necessário que o JOB que foi colocado em execução use uma variável global para o processo principal e de controle de jobs saber qual é o ThreadID deste processo, para ser possível um match com o retorno da GetUserInfoArray().

Seu processo principal pode não saber o que aconteceu com o processo filho, mas sabe que ele não está mais no ar, e saiu antes de dar um resultado. Isso muitas vezes é suficiente para você estudar uma forma de submeter o processo novamente, ou de encerrar o processo principal informando que houve um término anormal e os logs de erro do sistema devem ser verificados, ao invés de esperar para sempre um JOB que já não está mais lá.

Conclusão

Quanto mais nos aprofundamos em um tema, mais temas aparecem para nos aprofundarmos 🙂 E, é claro que veremos exemplos de uso práticos destes mecanismos, com fonte e tudo, nos próximos posts !!!

Agradeço novamente a audiência, e desejo a todos(as) TERABYTES DE SUCESSO !!! 

Referências

 

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s