Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

Portuguese

Pagetitle
Grid de Processamento AdvPL - INTERNA
Grid de Processamento AdvPL - INTERNA

Grid de Processamento AdvPL - INTERNA

O conceito de Grid Computing ou Grid de Processamento surgiu com a idéia de permitir aproveitar de forma otimizada o uso de recursos computacionais dispersos. Por exemplo, utilizar um excelente perfil de software existente em uma universidade, a fantástica capacidade de processamento existente em outra, a imbatível quantidade de display e/ou rendering existente em outra e assim por diante. Desde a criação do conceito de processamento em Grid, surgiram recursos e ferramentas que exploram essa tecnologia, como Grids de Computação de Alto Desempenho, Data Grids, Services Grids, OGSA e Web Services, entre outras.


 

Abrangência
ERP 10 e 11



O uso deste conceito pode abranger a integração entre equipamentos de uma sub-rede, em um datacenter, por exemplo, uma Intranet,ou ainda equipamentos conectados na Internet. De acordo com a necessidade de disponibilidade da informação, segurança e desempenho, é possível projetar aplicações para aproveitar o tempo ocioso destes ambientes para transformar dados em informações, ou ainda utilizar de forma coordenada e melhor aproveitada da capacidade de processamento de servidores dentro da mesma rede para atender a uma demanda. 


Uso em ambientes Empresariais

As soluções de software utilizadas em um ambiente empresarial estão cada vez mais focadas para processos on-demand, isto é, mediante a necessidade. Por exemplo, a inclusão de um ou mais pedidos de venda, de um ou mais produtos, inicia uma cadeia de processos interconectados orientada à fabricação dos produtos. Com o crescimento exponencial e imprevisível desta quantidade de processos, o uso de tecnologias em Grid é uma alternativa muito atrativa, pois havendo maior demanda, mais recursos são alocados, e havendo a diminuição desta demanda, os recursos são liberados para outras aplicações.

No modelo computacional atual, apenas uma pequena parte de capacidade de processamento é utilizada constantemente. A capacidade total somente é utilizada em momentos de pico, ou por determinados processos mais pesados, que quando executados superalocam recursos do ambiente, prejudicando o desempenho dos demais processos em andamento.

Partindo da execução simultânea de processos de forma distribuída, o uso de Grid em um ambiente empresarial oferece a possibilidade de diminuir o tempo de resposta de processos, aproveitando de forma disciplinada e mais uniforme os recursos de processamento e comunicação de infraestrutura de hardware e software do ambiente existente, a segurança de trocar a informação de parâmetros e retorno dos processos entre servidores em uma mesma sub-rede, e oferecendo também indicadores de desempenho e utilização da infraestrutura alocada, que apontam com mais precisão os recursos que devem receber upgrade para melhor atender às necessidades do ambiente. 


Introdução 

O Grid de Processamento AdvPL é um componente integrado ao Framework da linguagem AdvPL, que compreende o suporte à gestão de processos especialistas distribuídos. Altamente escalonável, compõe este cenário uma aplicação GridServer, coordenadora de distribuição de processos, uma aplicação Agente de Processamento, que é configurável em múltiplos serviços do servidor de aplicação (TOTVS | Application Server), e uma classe Cliente, que oferece ao desenvolvedor uma interface simples de utilização do recurso de distribuição de processos.

A ideia básica do Grid AdvPL é utilizar a capacidade de processamento de mais de um computador, simultaneamente, com o objetivo de realizar um processo longo e/ou pesado em menos tempo, dividindo o  processo em unidades menores de processamento menores, e distribuindo estas unidades entre os computadores envolvidos, para que estas unidades sejam processadas em paralelo, utilizando a infraestrutura de servidores Slave do servidor de aplicação (TOTVS | Application Server), configurados em modo de Balanceamento de Carga.

Imediatamente, imagina-se ser possível, por exemplo, partir de um processamento que demora 10 horas em um único computador, dividí-lo entre 5 computadores de mesma capacidade do original, e terminar o processo em 2 horas.

Embora esta ideia não esteja muito longe da realidade, o uso do Grid pode não se aplicar com sucesso para todos os processos longos de um sistema. Antes de utilizar o Grid, deve ser feito um estudo de caso, onde a eficácia da implementação depende do processo atender a alguns pré-requisitos específicos, onde serão avaliados diversos fatores, como o paralelismo e independência total entre as unidades de processamento, a quantidade de bytes de entrada para um processamento , a quantidade de bytes de saída, gerada pelo processamento, o tempo gasto com cada unidade de processamento, o custo de processamento dos mecanismos de controle, a segurança da informação, e inclusive a relação custo/benefício empregados na reestruturação de um processo para uso do Grid.

O Grid de Processamento AdvPL permite a codificação e/ou porte de uma aplicação AdvPL, para utilizar de forma simples um ambiente de processamento distribuído, onde o complexo controle de distribuição otimizada dos processos e tratamento de excessões é realizado pela camada de infraestrutura do Grid, onde a adequada parametrização dos processos e determinados pré-requisitos de comportamento dos processos garantem o sucesso da implementação.

 

 



Componentes da infraestrutura de Grid do AdvPL

 


GridServer - Coordenador de Processos Distribuídos

GridServer trata-se de um servidor de aplicação (TOTVS | Application Server), configurado como serviço. O GridServer em si não é um serviço que consome CPU do equipamento, porém deve ser criado e configurado um serviço exclusivo para esta finalidade, para fins de controle. É possível configurar apenas um GridServer por ambiente. O objetivo do GridServer é executar um JOB de controle dos processos, que deve ser especificado no arquivo de configuração do TOTVS | Application Server e iniciar este JOB, automaticamete, quando o serviço for iniciado.

Exemplo de configuração

[OnStart] 
Jobs=GridServer
RefreshRate=60
[GridServer]
Main=GridServer
Environment=<nome_do_environment>
 


Observação: O JOB GridServer deve ser especificado na seção [OnStart] do serviço, para chamar a função de gerenciamento GridServer. 


Comportamento e funcionalidade

  • Responsável pela coordenação e monitoramento dos Agentes disponíveis para processamento em Grid.
  • Possui apenas um processo de gerenciamento.
  • Ao receber uma solicitação de processamento em Grid, o GridServer verifica se existe a quantidade mínima disponível para realizar a operação, e aloca a seu critério, informando que existe um Client que precisa de processos livres. Cada agente alocado pelo coordinator conecta-se com o cliente para fazer parte do Grid.
  • O IP do equipamento, onde está o serviço do GridServer, e a porta TCP deste serviço deve estar liberada para aceitar conexões TCP dos Agentes configurados no Grid.

 

 



GridAgent - Agente Executor de Processos

GridAgent trata-se de um TOTVS | Application Server configurado como serviço. No GridAgent, devem ser especificadas quantas instâncias/processos (Threads) serão disponibilizadas para uso no Grid, para cada Agente. Pode ser utilizado um serviço que esteja ou não em uso para balanceamento de carga. Deve ser configurado um JOB, no arquivo de configuração, do TOTVS | Application Server, e o mesmo dever ser inserido na seção [OnStart], para iniciar automaticamente na execução do serviço.

A configuração do agente é praticamente idêntica para todas as máquinas que fazem para do Grid. Todas devem apontar para o GridServer, apenas devemos trocar o IP da máquina atual na configuração e o número da instância/processos quando conveniente.

Exemplo

[OnStart] 
Jobs=GridAgent
RefreshRate=60
[GridAgent]
Main=GridAgentAgent
IpAgentIp=<IP_da_máquina_atual>
Instances=<número_de_processo>
Environment=<nome_do_ambiente>
CoordServer=<IP_ou_nome_do_coordinator>
CoordPort=<Porta_tcp_coordinator>

 


Comportamento e funcionalidade

  • Ao iniciar, o serviço sobe o número de processos (Threads) configurado na chave Instances e cada processo estabelece  um conexão TCP com o Coordinator, identificando-se como um processo disponível para uso.
  • O Agente pergunta ao Coordinator se existe alguém solicitando o Grid, em intervalos de 5 segundos.
  • Ao ser alocado, o Agente estabelece uma conexão RPC com o servidor solicitante, executa a função de preparação de ambiente no seu processo, e pede ao solicitante um elemento para processamento.
  • A classe monitora as execuções, recupera os retornos de processamento e controla os status dos processos.
  • Ao final dos dados ou ao final do processo, o encerramento dos processos inspeciona se houveram elementos enviados e não processados.
  • Um erro fatal de execução em um Agente envolvido na operação pode interromper e abortar o processo do Grid, desconectando os outros agentes.

 

 



GridClient - Classe de Interface para Distribuição de Processos

 


Visão Geral

Utilizada pelo fonte Client, ou solicitante de processamento, permite a execução de processos distribuídos, independente de ser conhecida a quantidade de elementos que serão processados, possui os tratamentos de monitoramento e retorno de processos.

Uma solicitação de uso do Grid, através da classe GridClient, inicia o processo mediante uma conexão com o GridServer, que fará a alocação dos Agentes disponíveis para o processo em uso pelo GridClient, entregando as solicitações de processamento aos Agentes conectados, acompanhando o andamento dessas requisições e retornando, ao final do processo, as informações de status pertinentes à execução.

Basicamente, o objeto Client do Grid possui tratamentos internos no curso das etapas da operação, que não permitem determinadas etapas serem executadas mais de uma vez, nem a tentativa de reutilizar uma instância do objeto Client já utilizada em um processo. A sequência correta e esperada de operações é:

  • Criar o objeto Client.
  • Parametrizar o objeto Client, se necessário.
  • Executar o Grid em modo Batch (BatchExec) ou em modo Dinâmico (Prepare/Execute/Terminate).
  • Se qualquer uma das etapas ou métodos retornar falso (.F.), deve ser verificado inicialmente o método GetError() da instância, algumas propriedades de controle que contém dados adicionais e, em seguida, esta instância deve ser descartada. Qualquer recuperação ou nova tentativa deve recomeçar o processo, criando uma nova instância do Grid.
  • Finalizado o processo em Batch, o objeto Client é automaticamente terminado e, em caso de retorno falso (.F.), as propriedades de controle adicionais devem ser verificadas. Em uso dinâmico, a finalização de processo (Terminate) deve ser acionada via programa, e o retorno da mesma determinará se o processo foi concluído com sucesso ou se houve alguma falha na finalização, onde as propriedades de controle adicionais devem ser verificadas.
 


Os métodos, propriedades de controle e demais comportamentos serão detalhados na documentação da classe Client e no exemplo didático de uso do Grid.

Método

New()
DescriçãoConstrutor do objeto Client do Grid.
ParâmetroNenhum
RetornoRetorna o objeto do Grid Client.
UtilizaçãoDeve ser utilizado pelo programa solicitante do Grid, para criar um objeto para uso do Grid de processamento.
ComportamentoAo ser criado, a instância do GridClient apenas inicializa as propriedades da classe no processo local para uso e cria um identificado único para o processo solicitante. Neste momento, ainda não é realizada nenhuma conexão com o Coordinator. Após a criação deste objeto, podemos alimentar algumas propriedades do objeto que vão definir o comportamento do Grid para este processamento.
RestriçãoNão pode ser criado mais de um objeto GridClient na mesma thread/processo solicitante.
MétodoPrepare(<cFnStart>, [aStartParms], <cFnExec>, [cFnExit])
DescriçãoPrepara o Grid para execução do processo.
Parâmetros
  • cFnStart -Indica o nome da função utilizada pelos agentes para preparar a thread que executará o Grid.
  • aStartParms - Indica o array de parâmetros a ser passado para a função de preparação. Caso não seja informado, a função especificada em <cFnStart> receberá como parâmetro um array vazio.
  • cFnExec - Indica o nome da função que será utilizada para receber e processar cada unidade de processamento do Grid.
  • cFnExit - (Parâmetro opcional) Indica o nome da função utilizada pelos agentes para ser executada quando o Grid for finalizado ou terminar o processo em questão.
Retorno

Retorna verdadeiro (.T.), em caso de sucesso, indicando que o Grid está pronto para receber requisições; caso contrário, falso (.F.), em caso de falha na preparação do Grid.

Para mais informações sobre as causas da falha, consulte o método GetError().

Comportamento

A etapa de preparação deve ser executada, quando o Grid for utilizado para envio dinâmico das requisições de processamento. Isto é, não temos exatamente a quantidade de requisições que serão distribuídas ou não é viável criar um array com todas as requisições para executar o Grid em modo Batch. A etapa de preparação conecta o programa solicitante com o GridServer (Coordinator) e envia o pedido de solicitação de processamento. O Grid Server por sua vez, ao receber o pedido, avalia se existem agentes disponíveis para processar e informar os agentes a serem alocados de qual máquina/ambiente/processo foi realizada a solicitação. Cada agente alocado conecta por RPC no serviço solicitante, verifica se existem os pré-requisitos para a execução da função de preparação de ambiente, executa a função de preparação de ambiente e informa ao GridServer se este agente foi preparado com sucesso.

Restrição

O método de preparação somente poderá ser executado uma vez na instância do Grid, e deve ser executado antes de enviar requisições de processamento.

MétodoExecute(<aCallParm>)
DescriçãoEnvia uma requisição de unidade de processamento a um processo de agente disponível no Grid.
Retorno

Retorna verdadeiro (.T.), em caso de sucesso, no envio da requisição; caso contrário, falso (.F.) em caso de falha de execução no Grid.

Para mais informações sobre as causas da falha, consulte o método GetError().

Comportamento

O método Execute() envia o array de parâmetros da requisição <aCallPar> para um dos agentes preparados e disponíveis para processamento. Caso não hajam agentes disponíveis, o programa verifica se existem notificações de processamento concluído de algum agente conectado, obtém o retorno caso existe e envia a requisição novamente. Caso não hajam retornos pendentes, é verificado se os agentes alocados para processamento estão efetivamente no ar. Havendo agentes on-line e ocupados, a função aguarda um agente terminar o processo em andamento no momento, para enviar a requisição de processamento. Uma vez enviada a requisição, o método retorna verdadeiro (.T.) caso todos os agentes tenham caído (não estão mais em processamento) ou o número de agentes on-line não seja suficiente para a operação prosseguir; caso contrário, é retornado falso (.F.). Se uma operação de Execute() retornar falso (.F.), o Grid deve ser finalizado e o processo deve ser interrompido, através do método Terminate().

MétodoTerminate()
DescriçãoFinaliza um processo em Grid.
ParâmetroNenhum
Retorno

Retorna verdadeiro (.T.), em caso de sucesso, indicando que o Grid foi finalizado; caso contrário, falso (.F.), em caso de falha na finalização do Grid.

Para mais informações sobre as causas da falha, consulte o método GetError().

Comportamento

Ao ser chamado, o método informa ao Coordinator que o processo deve ser finalizado. Caso ainda existam agentes em execução, o GridClient espera pela finalização dos agentes para certificar-se que o processo foi concluído com sucesso. Este método deve ser chamado quando o Grid for executado fora do modo Batch, e houve um retorno falso (.F.) do método Execute(), para finalizar o processo em andamento. Após a execução do método Terminate(), devem ser verificados os status de processamento do GridClient, através de propriedades especificas.

Uma vez terminado, o mesmo objeto do Grid não pode ser inicializado novamente, devendo ser descartado, para ser possível então criar uma nova instância do GridClient, caso necessário.

MétodoGetError()
DescriçãoRecupera uma string contendo o último erro registrado pela classe Client do Grid.
ParâmetroNenhum
RetornoRetorna uma string com a ocorrência de erro codificada. Caso não haja nenhum erro registrado na interface Client do Grid, esta função retornará uma string em branco ("").
 

 



Estruturando uma Aplicação AdvPL para Grid

 


Visão Geral

A aplicação AdvPL escrita para utilizar Grid, deve ser dividida em 3 partes:

  • Função Client ou solicitante do processamento.
  • Função de preparação de ambiente de processamento.
  • Função de execução de unidade de processamento.
 


Na prática, um determinado processo não será dividido automaticamente para ser processado simultaneamente em mais de um serviço/servidor TOTVS | Application Server. O processo deve ser avaliado, revisado e as etapas paralelizáveis do processo deverão ser encapsuladas para serem processadas através do Grid, onde será utilizado um modelo de Working Thread, para que uma ou mais etapas de um processamento não-concorrentes entre si possam ser executadas desta forma, e as funções de preparação de ambiente e execução não realizem nenhuma operação de interface (abertura de janelas, pop-up, perguntas, etc) durante o processo.

As funções envolvidas diretamente em um processo para uso do Grid são especialistas, isto é, são construídas sob medida para um determinado conjunto de processos, para utilizar de forma inteligente e otimizada os recursos do Grid. A função de preparação de ambiente será executada uma vez para cada agente do Grid que será responsável por uma parte do processamento. A função de execução de requisição de processamento será chamada pelo GridServer, no ambiente criado pela função de preparação, para cada requisição de processamento que se fizer necessária, e a função Client, ou solicitante de processamente, será a responsável por iniciar este processo, definir o que será processado, utilizar a classe Client do Grid para a realização do processamento distribuído, e ao final do processo, recuperar as informações e/ou ocorrências de falha de processamento.

Terminado o processo, os ambientes dos Agentes utilizados são finalizados, e os processos dos Agentes são terminados. Em alguns segundos, cada Agente verifica a quantidade de processos de Agentes iniciados, e estando abaixo do configurado, novos processos são iniciados para as próximas utilizações do Grid.

Tomando por base o ambiente do ERP Microsiga Protheus, que envolve um servidor de Banco de Dados, um conector SGBD (TOTVS | DBAccess), um servidor de arquivos ISAM para dicionários (SXS) e um ou mais servidores Slave para atender à conexões remotas de usuários (Remote), um determinado processo pode envolver a busca de dados nos SXS, a busca de dados no Banco de Dados através do conector SGBD, o processamento efetivo da unidade de processamento e a inserção ou update do resultado do processamento novamente no Banco de Dados.

Para uma aplicação em Grid ser eficiente neste ambiente, os dois principais pontos a serem avaliados são pré-requisitos operacionais das unidades de processamento (processo de cada requisito do Grid), e configurar adequadamente a quantidade de processos por Agente do Grid.

 


Unidades de Processamento - Requisitos básicos

A função especialista de execução de unidades de processamento deve atender a alguns pré-requisitos para de forma geral ser eficiente em Grid. Sendo:

  • Paralelismo e independência

Isto significa que cada unidade de processamento não devem ter pontos críticos que exigam tratamento mutuamente exclusivo entre si. Vamos conceituar este acesso exclusivo no seguinte exemplo: uma unidade de processamento requer o posicionamento em um determinado registro, e deve obter um “Lock” deste registro para atualização. Efetivamente, não há problema em uma situação destas existir, desde que seja eliminada ou minimizada ao máximo, de modo a evitar a todo o custo que um ou mais processos de Grid tentem adquirir o lock deste registro, pois isto implicaria na serialização do processo. Não adianta todos os processos de Grid executarem em paralelo em máquinas diferentes, se o processo de atualização do resultado requer uma serialização, onde um processo executado em um agente precise esperar outro processo terminar para conseguir atualizar um resultado e continuar o seu processamento.

A independência do processo, significa que não deve haver nenhuma dependência ligada à ordem de execução de cada elemento de processamento. Por exemplo, em uma lista de 1000 processos, um determinado processo na posição 750 da lista, pode depender da finalização da requisição 650, pois ela ainda pode estar em execução por um Agente, e criar controles para que um processo espere outro terminar causa um orverhead desnecessário a prejudicial à performance do Grid, envolvendo novamente a serialização do processo. Da mesma forma, o Grid não garante que a ordem de execução dos processos na lista seja respeitada. A distribuição é sequencial, mas o elemento de processamento 2 pode começar em uma máquina antes do elemento 1.

Em suma, um processo ideal para Grid não deve entrar em modo de espera por nenhum recurso, seja ele um registro, arquivo, dispositivo e etc. O recurso deve estar disponível, pois mesmo que seja necessário uma trava neste recurso, para que um processo externo ao Grid não acesse o mesmo durante um processamento, caso o Grid não consiga bloquear o recurso justamente por ele estar sendo usado por uma aplicação externa, o processo deve evitar a todo custo esperar esse recurso estar disponível para continuar processando, como por exemplo entrar em loop tentando obter um lock.

Grande parte dos processos pode precisar de um recurso em modo exclusivo em determinado momento. O objetivo da análise do processo é prepará-la para minimizar ao máximo este tipo de ocorrência.

 


  • Bytes de E/S X tempo de cada unidade de processamento

Uma unidade de processamento vai receber os parâmetros montados pelo programa cliente do Grid ou solicitante. Esta entrada compõe um bloco de informações com um determinado tamanho, fixo ou variável. Quando a unidade de processamento receber estes parâmetros, a mesma pode precisar de mais informações, obtidas por exemplo pelo processo mediante uma consulta ao banco de dados, que vai trafegar mais blocos de dados pela rede, usados no processo. Todos esses blocos são classificados como dados de Entrada de uma unidade de processamento.

Terminada a execução da unidade de processamento, os dados gerados pela unidade deve ter uma saída. Estes dados de saída normalmente compõe a inserção ou atualização de registros na base de dados. As informações geradas pela unidade de processamento são classificadas como dados de Saída.

Desta forma, podemos mensurar que, em uma determinada unidade de processamento, onde foram usados X Bytes de entrada, e Y Bytes de Saída, foram necessários Z segundos para esta unidade. Logo, houve um tráfego de rede de X + Y Bytes para E/S do processo, e o tempo mensurável Z engloba o tráfego destes dados e o processamento efetivo dos dados. A partir dessas informações, aplicadas em uma fórmula simples, é possível obter um coeficiente de operação, que ajuda a decidir se este processo será eficaz se colocado em um Grid.

Em se tratando de processos complexos e parametrizáveis, que envolvem geralmente mais de uma rotina, onde as rotinas já estão codificadas para execução única em um equipamento, obter as informações de Bytes E/S e o tempo em segundo para o cálculo deste coeficiente torna-se uma tarefa complexa.

A linguagem AdvPL, em constante processo de inovação e melhoria, está ganhando novos recursos de monitoramento, que vão permitir mensurar estes indicadores de forma mais simples, facilitando esse processo. Porém, mesmo sem este indicador no momento, uma análise de pontos críticos de código e utilização de recursos do processo é suficiente para determinar a viabilidade do processo em Grid. Como esta questão envolve muitos fatores, este ponto da análise será detalhado em tópico específico, fazendo uso de um exemplo prático e didático de uso do Grid.

 


  • Segurança da Unidade de Informação

Um processo projetado e codificado para execução em apenas uma estação servidora, deve possuir tratamentos de erro e excessões, prevendo uma gama de possibilidades, tais como: tratamento de erro fatal (erro no código-fonte), utilização de blocos transacionados de operações de Banco de Dados para evitar corrompimento dos dados e alguns processos longos ainda possuem um mecanismo próprio de log e status, que permite continuar um processamento que foi interrompido, intencionalmente ou não.

Quando utilizado um Grid de Processamento, essas proteções devem ser mantidas, visando porém apenas garantir que não seja gerado um resultado incorreto ou corrompido, e as transações devem ser as mais curtas possíveis, atentas também aos quesitos de independência e paralelismo. Neste cenário, onde requisições de processamento são distribuídas para vários computadores e ambientes, em caso de ocorrência de erro fatal, o Grid é capaz de retornar os detalhes desta ocorrência ao programa solicitante, e o programa solicitante define o comportamento que o Grid deverá assumir neste caso. Deve-se atentar também ao fato de, existindo muitos mecanismo de controle para tratamento de excessões, isto pode interferir no desempenho da aplicação, e acabar criando um código-fonte muito complexo para receber manutenção ou melhorias. Quanto mais controles inserirmos, para o processo ser capaz de recuperar esses tipos de ocorrência automaticamente, ou até mesmo permitir um reprocessamento parcial de um processo em Grid que não foi finalizado com sucesso, mais árdua é a tarefa de garantir a segurança da informação.

O Grid possui tratamentos para determinar se uma requisição de processamento enviada a um Agente foi retornada, se um ou todos os Agentes foram derrubados ou caíram durante um processo e, inclusive, se um determinado processo foi interrompido por ocorrência de erro fatal do programa. O comportamento do Grid quando detectada uma ocorrência desta natureza será explicado posteriormente, no exemplo didático de uso do Grid.

O foco central da segurança do Grid, é montar a lista de unidades de processamento com dados previamente validados, que garantam a execução da rotina a que se propõe, para que o processo inteiro do Grid não seja invalidado devido à falta ou inconsistência de algum parâmetro, e o programa responsável pela unidade de processamento deve garantir que uma ocorrência de erro fatal ou crítica não gere um resultado incompleto, por exemplo gravar um registro pela metade na base de dados (utilizar transação no Banco de Dados).

 

 



Configuração de Agentes e Processos X Agentes

 


Visão geral

Um Agente é um serviço do TOTVS | Application Server, que será configurado para prover ao Grid uma quantidade fixa de processos (Threads), que serão alocados para uso com o Grid.

A execução de requisições de processamento por mais de um computador ao mesmo tempo no Grid utilizará mais recursos da rede, do Banco de Dados, do servidor de arquivos ISAM e da capacidade de processamento de cada máquina envolvida no processo. Enquanto o processo do Agente não foi solicitado para um processamento, o consumo de CPU, memória e recursos do Servidor-Agente em questão, e dos demais componentes distribuídos (Banco de Dados, Dicionários, Rede) envolvidos no processo. 


  • Relação entre processo e processador (CPU)

Tomando por base um processamento hipotético de cálculo de uma lista de operações, realizada hoje por um programa que faz um cálculo por vez, de forma sequencial, utilizando apenas recursos da CPU. Se dividirmos a lista, e colocarmos dois processos de cálculo para rodar ao mesmo tempo no mesmo equipamento, em se tratando de uma máquina com um processador (single-core, sem hiper-threading), o computador vai internamente rodar uma parte de cada processo, pois não são efetivamente dois processos simultâneos. Quanto mais dividimos a lista e colocamos mais processos, mais CPU da máquina é utilizada, e uma parte dos recursos de processamento são consumidos pelo sistema operacional do equipamento para trocar o contexto do processo e os status de execução para rodar uma parte de cada processo por vez. A partir do momento que a CPU do equipamento atingiu 100% de utilização, não adianta colocar mais processos, pois não haverá mais ganho de performance no processo.

Neste cenário, quando utilizamos mais de uma CPU, por exemplo em dois computadores distintos, cada requisição de processamento será processada simultaneamente, e quanto mais computadores utilizamos para processos simultâneos, realizamos mais processos por segundo e diminuimos o tempo de processamento total. Em linhas gerais, quanto mais Agentes distribuídos em computadores distintos nós configuramos, maior é o paralelismo do processo. E, com a tecnologia dos processadores multi-core e servidores com mais de um processador, obtemos um ganho de performance e melhor utilização da capacidade de processamento destes equipamentos distribuindo o processamento usando mais de um Agente no mesmo equipamento.

 


  • Configuração de Agentes de Processamento para Grid

Para o uso do Grid, é utilizado um ambiente com um ou mais servidores slave, configurados para execução de aplicações no mesmo ambiente, de forma semelhante à configuração de balanceamento de carga. É possível configurar os serviços slave, do TOTVS | Application Server, já utilizados no ambiente para balanceamento de carga para também serem Agentes do Grid, como também é possível utilizar um ou mais equipamentos distintos para colocar apenas serviços do TOTVS | Application Server exclusivos para serem Agentes do Grid, ou inclusive ambos simultaneamente.

É possível configurar um ou mais servidores do ambiente, em máquinas distintas, para uso exclusivo de Agentes para Grid, onde pode ser configurado um número maior de processos por Agente. Neste cenário, o uso total da capacidade de processamento da CPU não interfere diretamente nas conexões e processos executados pelas aplicações Remote, que não estão conectadas nestes servidores. Por outro lado, existem duas desvantagens no uso desta configuração: Os processos em execução durante o uso do Grid podem atingir um limite de processamento do Banco de Dados ou tráfego de rede entre os servidores, que afetaria indiretamente os demais processos do ambiente, e como estas máquinas possuem serviços para uso exclusivo do Grid, a capacidade de processamento delas não será utilizada quando não houver nenhum processo utilizando o Grid.

A melhor alternativa é utilizar ou montar um ambiente de balanceamento de carga, do TOTVS | Application Server, para habilitarmos também o uso de Grid. Entretanto, deve-se dimensionar adequadamente o número de Agentes por máquina e o número de processos por Agente, pois o excesso de processos por Agente pode prejudicar os demais usuários de Remote e/ou outros programas em execução naquele servidor, e/ou gerar gargalos de banco e/ou rede.

Inicialmente, configuramos por máquina, um serviço do TOTVS | Application Server para cada processador e/ou Core de processador disponível na máquina. Por exemplo, em uma máquina bi-processada, configuramos os serviços de Agente no equipamento. Em uma máquina Core2-Quad, com uma CPU com 4 core, configuramos 4 servidores TOTVS | Application Server e assim por diante. Em seguida, deve ser configurado o número de processos (instances) por Agente. Deve-se iniciar com um número baixo, por exemplo um ou dois processos por Agente.

Realizadas as configurações do GridServer, do serviço de Balanceamento e dos Agentes, a próxima etapa consiste em usar uma ou mais aplicações que fazerm uso do Grid, para verificar o quanto de recurso esta sendo consumido de CPU nas máquinas Agente, e se o servidor de Banco de Dados esta dando conta das requisições. Não deve-se subir muito a quantidade de processos por agente, como já dito anteriormente, isso pode prejudicar a performance dos demais processos enquanto o Grid está sendo utilizado. Lembre-se que estes serviços de Agente também estarão processando conexões de estações remotas nele.

Em ambientes onde já existe uma configuração de balanceamento de carga entre servidores TOTVS | Application Server, e nesta infraestrutura cada serviço slave será também configurado como um Agente, devemos antes de mais nada verificar se o uso normal do sistema e de seus usuários remotos conectados não estão consumido a capacidade total de processamento neste ambiente, mantendo a CPU dessas máquinas em 100%. Neste caso, configurar os Agentes em um ambiente já carregado não vai oferecer ganho de performance.

 


  • Considerações sobre o ganho obtido com o Grid

Dado o número de variáveis envolvidas, o percentual de ganho obtido com o uso do Grid varia de acordo com o tipo de processamento realizado, consumo de recursos de CPU, rede e banco de dados. O ganho mensurável, em linhas gerais e para a grande maioria dos processos, dificilmente conseguirá uma progressão geométrica de ganho. Por exemplo, um processo que demora 10 minutos quando executado em um computador, não vai demorar 5 minutos quando executado em um Grid com 2 processos ou 2 Agentes com um processo cada. Para um determinado processo em Grid, corretamente dimensionado, sem gerar gargalos em banco e rede, ter um ganho médio de 40% no processo usando a configuração acima é um resultado excelente, e dentro da realidade. 

 

 



Guia de mensagens, erros e ocorrências

As mensagens de erro e ocorrências do Framework do Grid, são codificados para facilitar a busca pelas informações de cada tipo de ocorrência. Como são 3 componentes distintos e integrados, GridAgent, GridClient e GridServer, as mensagens são prefixadas com GRIDSnnnn, GRIDAnnnn e GRIDCnnnn, respectivamente, onde nnnn corresponde ao identificador da ocorrência.

Mensagens GRIDSnnnn

Mensagens GRIDAnnnn

Mensagens GRIDCnnnn  


Mensagens GRIDSnnnn

As ocorrências com este prefixo, indicam que o componente diretamente envolvido é o GridServer.

 


[GRIDS0001] GridServer already started on Environment [<environment>]

Esta ocorrência é apresentada no console do GridServer, ao iniciar o JOB do GridServer na subida do serviço do TOTVS | Application server, onde não foi possível criar o lock de processamento do JOB GridServer no ambiente <environment>.

Esta ocorrência normalmente indica que, foi configurado mais de um serviço do TOTVS | Application Server para ser o GridServer do ambiente. O JOB de coordenação GridServer deve ser único por ambiente.

Existe também a possibilidade deste processo de lock falhar, por ausência de direito de escrita na pasta de semáforo do ERP, ou falha de acesso de criação de arquivo nesta pasta pelo serviço atual que está subindo o GridServer. Neste caso, deve ser verificado o compartilhamento utilizado para acessar o ambiente, e se o usuário utilizado para subir o serviço do TOTVS | Application Server possui os direitos necessários (FULL) no RootPath compartilhado configurado para o ambiente <environment>.

 


[GRIDS0002] GridServer Components Build MISMATCH.

Esta ocorrência é reproduzida na subida do JOB de controle do GridServer, caso sejam aplicados erroneamente patches de versões diferentes dos componentes do Grid no mesmo repositório. Cada componente do Grid (Agente, Cliente e Server) possuem códigos distintos, e controles de versão interdependentes, de modo que o ambiente para execução de Grid apenas é válido quando o Repositório contém a mesma versão dos três componentes. Esta verificação também é realizada pelo componente do Agente ao conectar com o GridServer, pelo Cliente ao conectar com o GridServer, e pelo Agente ao conectar com o Cliente, retornando uma mensagem de erro semelhante, porém com código diferente, com causas de origem semelhante.

Neste caso, deve ser verificado o histórico de atualizações do Repositório, e a partir de que atualização esta ocorrência começou a ser reproduzida. É possível também resolver esta ocorrencia, adquirindo o último patch de atualização da LIB/Framework da versão em uso, e aplicando ele de forma integral no repositório em uso. 


[GRIDS0003] GRIDSERVER ERROR ON ENVIRONMENT [<environment>]

Esta ocorrência indica que houve um erro fatal no componente GridServer. Juntamente desta ocorrência, é gerado um log de erro, gravado no arquivo error.log do ERP, e também apresentada/registrada no log de console do TOTVS | Application Server. Deve ser verificados os detalhes da ocorrência, e a ocorrência deve ser encaminhada ao suporte e/ou Help-Desk, mediante abertura de chamado, para investigação e tratamento adequado.

 

 



Mensagens GRIDAnnnn

As ocorrências com este prefixo, indicam que o componente diretamente envolvido é o GridAgent, ou Agente de processamento. 


[GRIDA0001] CONFIG ERROR : COORDSERVER not configured.

Quando o JOB do Agente é inicializado, são lidas as configurações da seção GridAgent do arquivo de configuração do TOTVS | Application Server. Caso a chave de configuração COORDSERVER não seja encontrada, ou não tenha conteúdo, o JOB do Agente é abortado durante a subida, informando esta ocorrência. Verifique as configurações do Agente no arquivo de configuração do TOTVS | Application Server. A chave COORDSERVER deve ser preenchida com o IP do servidor onde o serviço do GridServer está instalado. 


[GRIDA0002] CONFIG ERROR : COORDPORT not configured.

Quando o JOB do Agente é inicializado, são lidas as configurações da seção GridAgent do arquivo de configuração do TOTVS | Application Server. Caso a chave de configuração COORDPORT não seja encontrada, ou não tenha conteúdo, o JOB do Agente é abortado durante a subida, informando esta ocorrência. Verifique as configurações do Agente no arquivo de configuração do TOTVS | Application Server. A chave COORDPORTdeve ser preenchida com a porta de conexão TCP do serviço do GridServer. 


[GRIDA0003] CONFIG ERROR : AGENTIP not configured.

Quando o JOB do Agente é inicializado, são lidas as configurações da seção GridAgent do arquivo de configuração do TOTVS | Application Server. Caso a chave de configuração AGENTIP não seja encontrada, ou não tenha conteúdo, o JOB do Agente é abortado durante a subida, informando esta ocorrência. Verifique as configurações do Agente no arquivo de configuração do TOTVS | Application Server. A chave AGENTIP deve ser preenchida com o IP do servidor atual, onde o Agente está instalado.

 


[GRIDA0004] RPC CONNECT FAILED to [<CoordSrv>] Port [<cCoordPort>]

Quando o JOB do Agente é inicializado, após serem lidas as configurações da seção GridAgent, do arquivo de configuração do TOTVS | Application Server, o processo do Agente estabelece uma conexão RPC AdvPL com o GridServer. Caso não seja possível estabelecer esta conexão, pois os parâmetros informados na configuração não apontam para um GridServer válido, ou o serviço do GridServer não esteja no ar, ou mesmo não seja possível estabelecer a conexão devido à alguma indisponibilidade de rede ou restrição (Firewall na máquina do GridServer por exemplo), o JOB do Agente é abortado durante a subida com esta ocorrência, informando em CoordSrv o IP do GridServer utilizado, e em cCoordPort a porta TCP de conexão utilizada. Verifique se todas as condições acima estão sendo atendidas corretamente.

 


[GRIDA0005] Coordinator Service OFFLINE.

Quando o JOB do Agente estabelece uma conexão com sucesso no GridServer, é verificado se o JOB de controle do GridServer está no ar. Caso o JOB de controle do GridServer não esteja no ar, o JOB do Agente é abortado durante a subida, informando esta ocorrência. Verifique se os parâmetros de configuração do Agente estão efetivamente apontando para um GridServer, e se não ocorreu algum tipo de ocorrência de erro fatal no GridServer, que tenha ocasionado falha na subida do processo no GridServer. 


[GRIDA0006] GridAgent [<AgentVersion>] and GridServer [<ServerVersion>] Version MISMACH.

Após o Agente conectar com o GridServer, é verificado se a versão do Agente em uso é a mesma utilizada pelo GridServer. Caso os componentes não tenham a mesma versão, o ambiente de execução não é apropriado para a execução do Grid. A mensagem informa em AgentVersion a versão do componente Agente, e em ServerVersion a versão em uso pelo GridServer. Esta ocorrência será apresentada e registrada no log de console do Agente e do Coordinator. A causa mais comum desta ocorrência é o GridServer estar utilizando um repositório diferente do Agente.

 


[GRIDA0007] RPC CONNECT FAILED to Client [<cIP>] Env [<cEnv>] Port [<Port>]

Quando o JOB do Agente é alocado para atender à solicitações de um cliente do Grid, o Agente alocado estabelece uma conexão RPC com o servidor onde o cliente está sendo executado, para atender às solicitações de processamento da aplicação. Caso não seja possível estabelecer uma conexão com o Cliente, o Agente é abortado com esta ocorrência, onde o IP da estação cliente é informado em cIP, o ambiente é informado em cEnv, e a porta de conexão TCP utilizada pelo cliente é informada em Port. A falha de conexão pode ser devido à alguma indisponibilidade de rede ou restrição (Firewall na máquina do cliente, por exemplo). Verifique se estas condições estão sendo atendidas corretamente.

 


[GRIDA0008] GridAgent [<AgentVersion>] and GridClient [<ClientVersion>] Version MISMACH.

Quando o JOB do Agente é alocado para atender à solicitações de um Cliente do Grid, após estabelecer conexão RPC com o Cliente, é verificada se a versão do Agente é a mesma versão do Cliente. Caso as versões dos componentes não sejam as mesmas, o processo do Agente é finalizado com esta ocorrência, informando em AgentVersion a versão do componente do Agente e, em ClientVersion, a versão do componente Cliente. Esta ocorrência será apresentada e registrada no log de console do Agente e do Cliente. A causa mais comum desta ocorrência é o Agente estar utilizando um repositório diferente do Cliente.

 


[GRIDA0009] Start Function [<OnStart>] not found on [<cIP>] Env [<cEnv>] Port [<Port>] 

[GRIDA0010] Connect function [<OnConnect>] not found on [<cIP>] Env [<cEnv>] Port [<Port>] 

 [GRIDA0011] Exit function ['<OnExit>] not found on [<cIP>] Env [<cEnv>] Port [<Port>]

Quando o JOB do Agente é alocado para atender à solicitações de um Cliente do Grid, o Agente recebe o nome das funções de inicialização de ambiente (<OnStart>) e execução do processo (OnConnect), e opcionalmente uma função de finalização de ambiente (OnExit). O Agente verifica se estas funções exitem efetivamente no ambiente de execução atual do Agente. Caso alguma das funções não exista, o processo do Agente é abortado com uma das ocorrências acima, informando o nome da função não encontrada, e as informações do Cliente (IP, Ambiente, Porta TCP). A causa mais comum desta ocorrência é o Agente estar utilizando um repositório diferente do Cliente. 


[GRIDA0012] Start function [<OnStart>] ERROR (view error.log for details)

O Agente alocado, executa a função de inicialização de ambiente para uso do Grid, especificada em <cOnStart>. Caso a execução desta função, no ambiente do Agente, resulte em uma ocorrência de erro fatal AdvPL, o erro é interceptado e registrado sob a ocorrência GRIDA0017, e o processo é finalizado com a ocorrência acima, informando o nome da função chamada. Deve ser verificado o log de erro do ERP (error.log), onde é registrada a ocorrência completa do erro, para determinar sua causa. 


[GRIDA0013] Start function [<cOnStart>] Invalid Type Return (Expected L)

Ao executar a função de inicialização de ambiente para uso do Grid, o retorno esperado desta função é um valor booleano. Caso a função de inicialização não retorne um valor booleano, o processo é abortado com esta ocorrência. Deve ser verificado o código-fonte da função de inicialização de ambiente, e corrigí-lo para que a função retorne um valor booleano. 


[GRIDA0014] Start function [<OnStart>] return .F. - Cannot Start Thread.

Ao executar a função de inicialização de ambiente para uso do Grid, o retorno esperado desta função é um valor booleano. O retorno verdadeiro (.T.) informa ao Agente que a inicialização de ambiente foi executada com sucesso, e o Agente pode prosseguir. Caso a função retorne falso (.F.), isto indica que não há condições favoráveis para uso do Grid, e o processo é abortado com a ocorrência acima. 


[GRIDA0015] Agent INVALID COMMAND RECEIVED [<Cmd>]

Esta ocorrência não é esperada no funcionamento do Grid. A camada de troca de mensagens entre o Agente e o Cliente é realizada mediante mensagens nomeadas, onde uma instrução <Cmd> precede a requisição. Caso o Cliente envie um comando não reconhecido ao Agente, o processo é abortado com esta ocorrência. Caso esta seja reproduzida, a abertura de chamado para investigação da mesma deve conter o log de Console do Agente, do Cliente e do GridServer, acompanhada dos arquivos de configuração (.ini) dos serviços envolvidos, e do repositório em uso. 


[GRIDA0016] Exit function ERROR ( view error.log for details )

Quando um Agente inicia um processo de execução, se a função de inicialização de ambiente foi executada, e existe função especificada para finalização do Ambiente (ou Exit Function), a função é executada quando o Agente finaliza o trabalho para o Cliente. Caso a execução da função opcional de finalização do ambiente apresente erro fatal AdvPL, esta ocorrência é registrada. Deve ser verificado o log de erro do ERP (error.log) para mais detalhes. 


[GRIDA0017] GRIDAGENT ERROR ON ENVIRONMENT [<cEnv>]

O ambiente do Agente possui tratamento de erro diferenciado, onde uma ocorrência de erro fatal AdvPL é registrada sob este código. Ao registrar a ocorrência, são gravados também os detalhes do Agente, e caso o processo em execução já envolva a solicitação de um Cliente, os dados do cliente também são registrados. Informações adicionais da ocorrência de erro são gravadas também no arquivo de log de erros do ERP (error.log). Deve ser verificada a pilha de chamadas e a ocorrência para determinar sua causa e ação corretiva. 


[GRIDA0018] FATAL ERROR IN TRANSACTION

Quando da reprodução de uma ocorrência de erro fatal GRIDA0017, caso a ocorrência em questão tenha ocorrido em uma chamada de função do ERP, onde havia controle de transação (Begin Transacion) ativo no momento da reprodução da ocorrência, isto é, a mesma estava em um bloco transacionado, a finalização do processo informa a ocorrência GRIDA0018, e o processo é finalizado imediatamente.

 

 



Mensagem GRIDCnnnn

As ocorrências com este prefixo, indicam que o componente diretamente envolvido é o GridClient, isto é, a classe Client que faz a interface com o Grid. Grande parte destas ocorrências são retornadas pelo objeto Client do Grid, através da chamada do método GetError().

As ocorrências que são efetivamente reproduzidas gerando uma ocorrência de erro fatal no AdvPL possuem esta referência na documentação. 


[GRIDC0001] Invalid GridClient() Direct Function Call

Faz parte do ambiente de execução do Client do Grid, uma função chamada GridClient(). Esta função é meramente um referencial, e não deve ser chamada de forma direta. Caso algum programa equivocamente faça uma chamada direta à função GridClient(), a aplicação é abortada com uma ocorrência fatal do AdvPL, com a mensagem acima. 


[GRIDC0002] GridAgent Config not found.

Quando utilizamos a classe GridClient, durante a preparação do processo no Client, a classe busca no ambiente atual as configurações do Agente de trabalho, para obter os dados do GridServer para realizar a alocação do Grid. Caso esta configuração (GridAgent) não esteja presente ou não seja localizada no arquivo de configuração (.ini) do TOTVS | Application Server em uso pela classe Client, o processo não será completo, e a mensagem acima é acrescentada ao registro de erro da classe Client. Verifique se existe configuração de GridAgent no servidor atual, onde estão especificados corretamente o IP do GridServer, a porta do GridServer, e o IP do Agente atual. 


[GRIDC0003] Grid ALREADY TERMINATED : Cannot reconnect.

Caso o processo de conexão com o GridServer esteja sendo realizado por uma instância da classe Client, que já foi utilizada para um processamento, e o processo já foi finalizado, não é possivel reaproveitar a mesma instância da classe. A tentativa de reconectar com o GridServer para aproveitar uma instância usada não é possível, e a mensagem acima é acrescentada ao registro de erro da classe Client.

 


[GRIDC0004] Agent Client ALREADY CONNECTED to Coordinator.

Caso uma instância da classe Client, erroneamente seja direcionada para conectar novamente com o GridServer, onde a classe Client já está conectada, a operação não é realizada, e a mensagem acima é acrescentada ao registro de erro da classe Client. 


[GRIDC0005] <nAgents> Número de agentes inicializados insuficiente. Grid cancelado.

Durante a etapa de preparação para o uso do Grid, o Cliente informa o GridServer, e aguarda por até 90 segundos por conexões do(s) agente(s) alocado(s) para início do processamento efetivamente. Caso, após este tempo, não existam agentes conectados, o processo não é concluído, e a mensagem acima é acrescentada ao registro de erro da classe Client.   


[GRIDC0006] RPC CONNECT FAILED to ['<cCoordSrv>] Port [<:cCoordPort>]

O processo Client estabelece uma conexão RPC com o GridServer para solicitar o uso do Grid. Caso não seja possível estabelecer esta conexão, o processo de inicialização falha, registrando esta mensagem no registro de erro da classe Client, informando o IP do GridServer em cCoordSrv, e a porta é informanda em cCoordPort. A falha de conexão pode ser devido à alguma indisponibilidade de rede ou restrição (Firewall na máquina do Cliente, por exemplo), ou ainda o serviço do GridServer não está iniciado. Verifique se estas condições estão sendo atendidas corretamente. 


[GRIDC0007] Agent Client NOT CONNECTED to Coordinator.

[GRIDC0008] Agent Client NOT CONNECTED to Coordinator.

[GRIDC0009] Agent Client NOT CONNECTED to Coordinator.

As ocorrências acima ([GRIDC0007/8/9]) possuem a mesma causa em comum: Uma etapa interna do Client foi executada, sem que exista efetivamente uma conexão com o GridServer. As mensagens respectivamente tem origem na verificação de processos disponíveis, processos alocados, e obter lista de processos, respectivamente. Caso sejam reproduzidas, estas ocorrências retornam condição de falha no Client, e são acrescentadas no registro de erro da classe Client. 


[GRIDC0010] Agent Client Already Prepared.

A etapa intermediária de preparação do ambiente para processamento deve ser realizada apenas uma vez. Caso algum processo tente preparar novamente uma instância do GridClient já preparada, o processo não é concluído, e esta ocorrência é acrescentada no registro de erro da classe Client. 


[GRIDC0011] Execute Error : Grid already terminated.

O processo de envio de requisição de processamento aos agentes alocados do Grid (método Execute) não pode ser realizado se a instância atual da classe Client foi finalizada. Caso este método seja chamado nestas condições, a requisição retorna .F. (falso), e esta ocorrência é acrescentada no registro de erro da classe Client.

 


[GRIDC0012] Agent Client NOT CONNECTED to Coordinator.

O processo de envio de requisição de processamento aos agentes alocados do Grid (método Execute) não pode ser realizado se a instância atual da classe Client não está conectada com o GridServer. Caso este método seja chamado nestas condições, a requisição retorna falso (.F.), e esta ocorrência é acrescentada no registro de erro da classe Client. 


[GRIDC0013] Agent Client not Prepared yet.

O processo de envio de requisição de processamento aos agentes alocados do Grid (método Execute) não pode ser realizado se a instância atual da classe Client não passou com sucesso pela etapa de preparação. Caso este método seja chamado nestas condições, a requisição retorna falso (.F.), e esta ocorrência é acrescentada no registro de erro da classe Client. 


[GRIDC0014] Grid Error while processing. Grid aborted.

O processo de envio de requisição de processamento aos agentes alocados do Grid (método Execute) não pode ser realizado caso o processo Client já tenha sido finalizado, devido à alguma ocorrência de erro fatal de processamento em algum Agente. Caso este método seja chamado nestas condições, a requisição retorna falso (.F.), e esta ocorrência é acrescentada no registro de erro da classe Client.

 


[GRIDC0015] Grid Agent Fatal Error on Process. Grid Aborted.

O processo de envio de requisição de processamento aos agentes alocados do Grid (método Execute), internamente também realiza a verificação do retorno de processos. Caso, durante esta verificação, alguma ocorrência de erro fatal de processamento foi reportada por algum Agente, o processo do Grid é finalizado. Caso este método seja chamado nestas condições, a requisição retorna falso (.F.), e esta ocorrência é acrescentada no registro de erro da classe Client.

 


[GRIDC0016] No Processes ON-LINE to Grid Operation.

O processo de envio de requisição de processamento aos agentes alocados do Grid (método Execute), possui tratamento interno para aguardar por um dos Agentes alocados estar disponível para o envio da requisição. Passados 10 segundos neste processo de tentativa de envio e verificação de retorno, o Client verifica quantos processos alocados estão em processamento efetivamente (estão no ar). Caso esta verificação não encontre nenhum agente no ar, o processo do Grid é finalizado, a requisição retorna falso (.F.), e esta ocorrência é acrescentada no registro de erro da classe Client.

 


[GRIDC0017] Agent Client Execute Process TIME-OUT

O processo de envio de requisição de processamento aos agentes alocados do Grid (método Execute), possui tratamento interno para aguardar por um dos agentes alocados estar disponível para o envio da requisição. Durante este tratamento, o Client pode aguardar até 5 minutos para que algum agente alocado termine a requisição em processamento, para poder receber outra requisição. Caso não haja nenhum agente disponível em até 5 minutos, o Client assume que houve alguma falha mais grave no processo, como a função de processamento em loop infinito, ou uma situação de congelamento dos processos. Neste caso, o processo Client é finalizado, a requisição retorna falso (.F.), e esta ocorrência é acrescentada no registro de erro da classe Client.

 


[GRIDC0018] Grid Abort due Error Notification Received.

O processo de verificação de retorno interno do Client verifica o retorno das requisições enviadas ao Grid. Caso alguma das requisições tenha recebido um retorno de ocorrência de erro fatal no processamento, a verificação do retorno acrescenta esta mensagem no registro de erro da classe Client. 


[GRIDC0019] UNKNOW RETURN COMMAND [<cRetCmd>]

Esta ocorrência caracteriza um erro fatal no Client, onde uma instrução interna de controle desconhecida, informada em <cRetCmd> foi retornada por um agente. Neste caso, o processo Cliente é abortado com uma ocorrência de erro fatal AdvPL com a descrição acima. 


[GRIDC0020] Terminate Error : Grid Already Terminated.

O processo do Client possui um método de finalização, que pode ser chamado internamente pelos componentes do Client, ou via programa AdvPL que manipula a instância. Em ambos os casos, apenas uma chamada ao método é permitida. Caso o método Terminate seja chamado mais de uma vez para a mesma instância, o processo não é executado, e esta ocorrência é acrescentada no registro de erro da classe Client. 


[GRIDC0021] Terminate Error : Grid NOT Connected

A chamada do método de finalização (Terminate) do Grid, não é permitida quando a instância atual do Client ainda não conectou com o GridServer. Neste caso, o processo de finalização apenas acrescenta esta ocorrência no registro de erro da classe Client. 


[GRIDC0022] Terminate Error : Agent Client Still Not Prepared.

A chamada do método de finalização (Terminate) do Grid, não é permitida quando a instância atual do Client ainda não tenha executado com sucesso a etapa de preparação do ambiente para o Grid. Neste caso, o processo de finalização apenas acrescenta esta ocorrência no registro de erro da classe Client.

 


[GRIDC0023] Terminate Error : No Agents on-line.

Ao executar a chamada do método de finalização (Terminate) do Grid, são verificados se ainda exitem requisições em processo. Caso o Client não encontra nenhum processo/agente no ar, o processo de finalização acrescenta esta ocorrência no registro de erro da classe Client.

 


[GRIDC0024] Terminate Error : Agent Response TIME-OUT !!! Agent(s) Still on-line !!!

Ao executar a chamada do método de finalização (Terminate) do Grid, o Client aguarda pelas requisições de processamento ainda em execução no(s) agente(s) alocado(s). Caso ainda existam agentes no ar, porém nenhum processo envie algum retorno em até 5 minutos, o Client assume que houve alguma falha mais grave no processo, como a função de processamento em loop infinito, ou uma situação de congelamento dos processos. Neste caso, o processo Client é finalizado, não é aguardado por mais nenhum retorno, a requisição retorna falso (.F.), e esta ocorrência é acrescentada no registro de erro da classe Client. 


[GRIDC0025] Terminate Error :  Process Pending List NOT EMPTY !!!

Após terminado o processo de finalização do Client (Terminate), todas as requisições de processamento enviadas deveriam ter sido processadas. Caso alguma requisição foi enviada a algum Agente, e não foram recebidos todos os retornos, esta mensagem é acrescentada no registro de erro da classe Client. A lista de processos pendentes pode ser recuperada na propriedade “aSendProc” da classe Client.

 


[GRIDC0026] Invalid use of ::BatchExec due non-batch mode config.

Quanto é criado o objeto Client do Grid, podemos definir se ele será chamado através de execução em Batch, ou execução dinâmica. Caso seja definida a propriedade lBatchMode com falso (.F.), para uso dinâmico, não é permitida a chamada do método BatchExec() do Grid para esta instância. Caso isto seja realizado, a requisição retorna falso (.F.), e a ocorrência acima é acrescentada no registro de erro da classe Client.

 


[GRIDC0027] Grid Client Process ALREADY PREPARED. Cannot run with BatchExec.

Quanto é criado o objeto Client do Grid, e seja optada pela execução em Batch, a preparação do Grid é realizada internamente pela classe. Se este processo já foi chamado uma vez pelo Grid, por exemplo na tentaiva erronea de reutilizar uma instância, a requisição retorna falso (.F.), e a ocorrência acima é acrescentada no registro de erro da classe Client.

 


[GRIDC0028] Invalid use of ::GridGauge in BLIND MODE.

O objeto Client do Grid identifica, no momento da criação, se ele está sendo executado a partir de um processo com ou sem interface (Remote). Caso o processo atual não tenha interface, o método interno de atualização de barra de processamento, utilizado pelo processo em Batch não pode ser executado. Caso esta situação seja reproduzida, a ocorrência acima é acrescentada no registro de erro da classe Client. 


[GRIDC0029] GRID PROCESS MANUALLY ABORTED.

A execução do Grid Client em modo Batch, mostra uma régua de processamento, onde existe um botão de cancelamento manual de processo. Caso ele seja acionado durante o processamento, e o Grid seja interrompido por esta ação, a mensagem acima é acrescentada no registro de erro da classe Client.

 

 



Exemplo de uso do Grid - Código-fonte de teste

 


/* ========================================================================== 
Código-fonte de teste do Grid Client - Utilização com Prepare() e Execute()
=========================================================================== */
User Function GridBeta()
Local aStart := {1,2}
Local oGrid
Local nTimer := seconds()
Local lGridOk := .f. , nI
// Cria o objeto Client de interface com o Grid
oGrid := GridClient():New()
// Define o nome das funções de preparação de ambiente e execução
cFnStart := 'U_TGRIDS'
cFnExec := 'U_TGRIDA'
lGridOk := oGrid:Prepare(cFnStart,aStart,cfnExec)
If !lGridOk
// Caso o Grid não tenha sido preparado com sucesso, recupere
// os detalhes e mensagem de erro através do método GetError()
MsgStop(oGrid:GetError(),"Falha de Preparação do Grid")
// Finaliza o processo
oGrid:Terminate()
// Este objeto não pode ser mais usado . Limpa
oGrid := NIL
ReturnEndif
// Parte pra execução – Envio de 200 requisições
For nI := 1 to 200
// Looping de envio de dados
// O parâmetro de execução enviado é un número
lGridOk := oGrid:Execute(nI)
If !lGridOk
EXIT
Endif
Next
If lGridOk
// Até aqui, sem erros? Ok, finaliza o Grid.
lGridOk := oGrid:Terminate()
Endif
IF !lGridOk
// Houve algum erro, ou no processamento, ou na
// finalização do Grid. Verifica os arrays de propriedades
If !empty(oGrid:aErrorProc)
// Houve um ou mais erros fatais que abortaram o processo
// [1] : Número sequencial da instrução enviada que não foi processada
// [2] : Parâmetro enviado para processamento
// [3] : Identificação do Agente onde ocorreu o erro
// [4] : Detalhes da ocorrência de erro
varinfo('ERR',oGrid:aErrorProc)
Endif
If !empty(oGrid:aSendProc)
// retorna lista de chamadas que foram enviadas e não foram executadas
// [1] Número sequencial da instrução
// [2] Parâmetro de envio
// [3] Identificação do Agente que recebeu a requisição
varinfo('PND',oGrid:aSendProc)
Endif
MsgStop(oGrid:GetError(),"Falha de Processamento em Grid")
Else
// Tudo certo
MsgInfo("Processamento completo com sucesso em "+str(seconds()-nTimer,12,3))
Endif
Return

STATIC _ReqNum := 0
// =====================================================================
// Preparação de ambiente
// Executada por cada agente, para preparar o ambiente para rodar
// a função de processamento do Grid
// Num Grid para executar funções que dependem de infraestrutura do ERP,
// neste ponto deve ser colocado um PREPARE ENVIRONMENT
// =====================================================================

USER Function TGRIDS()
Conout("[DEMO] Preparando Ambiente")
// Espera randômica, para consumir algum tempo (de 1 a 10 segundos )
sleep( Randomize(1000,10000) )
Conout("[DEMO] Ambiente Preparado")
Return .T.
// =====================================================================
// Execução de Requisições de Processamento
// Recebe como parâmetro o conteúdo informado ao método Execute()
// Caso não haja nenhuma necessidade de conteúdo retornado
// diretamente pela chamada, a função deve retornar NIL.
// Caso seja retornado qualquer outro valor, ele será
// armazenado pelo GridClient e poderá ser recuperado posteriormente
// =====================================================================

USER Function TGRIDA(xParam)
Conout("[DEMO] REQUISICAO ["+str(++_ReqNum,4)+"] Processando Parametro ["+str(xParam,4)+"]")
// Espera randômica, para consumir algum tempo ( entre 0,5 e 5 segundos )
sleep( Randomize(500,5000) )
Conout("[DEMO] REQUISICAO ["+str(++_ReqNum,4)+"] OK")
Return
 


Atenção
  • As chamadas da função Sleep(), neste código-fonte exemplo, foram colocadas apenas para consumir algum tempo de processamento por requisição.
  • Para executar este código-fonte, basta compilá-lo em um repositório, configurar o engine de Grid com no mínimo 2 agentes e executá-lo em um dos slaves configurados para ser um agente do Grid. No log de console dos serviços, do TOTVS | Application Server, serão emitidas mensagens dos programas ao serem executados.
 
  •  

 



TIPS - Desenvolvimento, programação e comportamentos

 

Escopo de variáveis e ambientes de execução

Cada processo de agente configurado para execução do Grid é um processo independente, que pode estar sendo executado em qualquer um dos serviços configurados como agente. Deste modo, todos os agentes configurados devem apontar para o mesmo ambiente, RPO , rootpath e ter a mesma parametrização. Cada processo de agente é responsável por montar o seu ambiente no Start do processo, para que ele esteja pronto para executar as requisições de processamento que o objeto Client do Grid vai distribuir. Deste modo, um processo de agente não têm e não deve ter nenhuma dependência com qualquer outra instância de agente, eles não devem trocar informações, um processo de agente não pode depender de outro para executar a sua tarefa.

No ambiente de execução destes processos de agente, as variáveis STATIC são mantidas no ar entre as requisições, de modo que, se existe a necessidade de se fazer algum cache de processamento válido para os processamentos daquela instância do agente, poderá ser utilizadas variáveis STATIC no código-fonte. Vale lembrar que os conteúdos destas STATIC estão presas à instância do agente, não são compartilhadas entre os agentes. 


Garantir o paralelismo de processos

As requisições de processamento enviadas ao Grid não devem ser concorrentes entre si, como por exemplo duas requisições distintas tentarem fazer um RecLock() do mesmo registro da base de dados. Senão, neste ponto, um processo obtém o lock e o segura por algum tempo, enquanto um ou mais processos param de processar para esperar o lock ser solto. Isto serializa o Grid, elimina o paralelismo dos processos e a possibilidade do Grid apresentar algum ganho de performance. 


Ocorrência de Erro Advpl de programas em Grid

O Grid foi preparado para, em caso de uma ocorrência de erro AdvPL em qualquer requisição de processamento, o engine de Grid é finalizado sem terminar o processo, informando uma ocorrência de erro. Um erro fatal durante o processo não é uma operação recuperável, o Grid não deve finalizar o processo em caso de um erro como “variable does not exist” ou “Type mismach” ou similar no processo, pois para todos os efeitos uma parte do processo não foi completa, e não há e não pode haver nenhuma tentativa de recuperação em um caso como esse, como por exemplo recuperar a requisição enviada e enviá-la a outro agente. Isto não será e não pode ser feito.

 


Passagem de parâmetros para as execuções dos agentes 

São suportados todos os tipos básicos do AdvPL, EXCETO Code-Block e/ou OBJETO. Arrays multi-dimensionais são suportados, desde que não contenha elementos que contenham code-blocks ou objetos. E, no caso de uso de um array, o tamanho total da soma dos elementos deste array não deve passar de 1MB. Se a execução de uma requisição atômica precisa de tantos parâmetros, é mais recomendável que o agente receba um índice ou uma informação que permita ele mesmo montar os seus parâmetros.

 


Veja também


Grid de processamento AdvPL - Configuração