BlackTDN Search

domingo, 3 de julho de 2011

Protheus :: Advpl : Processamento em Grid e Multi Thread – Números Perfeitos : Versão Final

Números Perfeitos foi totalmente reescrito para trabalhar usando o “Processamento em Grid” e “Multi Thread”.  Agora, parafraseando Ernesto Haberkorn, “Dividimos para Multiplicar”.

O uso do Processamento em Grid no Protheus é, de fato, bem simples, mas a forma de Programar e de controle, torna-se um tanto quanto “complicada” (o mesmo podemos dizer para o uso de “Multi Thread”). Números Perfeitos pretende ser um exemplo claro e simples do uso desses dois “paradigmas”. Usará ambos quando a configuração do Processamento em Grid estiver definido ou apenas o último, caso contrário.

Para começar a programar usando Processamento em Grid, primeiro, precisei entender e aprender como o Processamento em Grid foi programado em ADPL. Identifiquei a existência de uma Classe: GridClient e, considerando que por padrão, em ADVPL, todas as Classes são instanciadas com o Método :New(), utilizei as seguintes funções ClassDataArr()  e ClassMethArr() para me auxiliar a entender as Propriedades da Classe e seus Métodos. ClassDataArr( GridClient():New() )  retornou todas as Propriedades da Classe GridClient e ClassMethArr( GridClient():New() )  todos os métodos que eu poderia utilizar.

Dentre os Métodos retornados, os que me interessaram foram:

:New() : Instancia um novo objeto da Classe GridClient;

:ConnectCoord() : Verifica a configuração do Processamento em Grid e, se tudo ok, efetua a conexão entre os “Agents” e o “Coordinator”;

:GetError() : Retorna a última mensagem de erro;

:GetIdleThreads() : Retorna o número de Threads em estado “IDLE”;

:BatchExec() : Efetua e gerencia o Processamento em Grid;

:WaitReceiveAll() : Verifica se todos os Retornos foram Recebidos;

:Terminate() : Utilizado para verificar se todos os processos da Grid Terminaram corretamente ou Para forçar a Finalização; e

Dentre as Propriedades:

:lGridFinish : Identifica se o Processo foi Terminado.

Obviamente que todos os comentários acima não passam de inferência, uma vez que não encontrei Documentação Completa sobre a Classe. No “Chute” e “Tentativa e Erro” pude identificar as características de cada um.

Além de ClassDataArr()  e ClassMethArr(),  __FunArr() auxiliou-me na identificação de algumas funções para uso no exemplo tornando-o um pouco mais rico. Dentre elas: GetServerIP(), GetSrvIniName() (antes utilizava GetAdv97() para retornar o nome do arquivo INI de configuração do Protheus Server), ThreadId() , GetEnvServer() e PTInternal().

A afirmativa de que o Processamento em Grid no Protheus é bem simples pode ser comprovada com o fragmento de código abaixo:

//Instancio um Novo Objeto da Classe GridClient

oGClient := GridClient():New()

//Verifico se é possível Conectar-se

IF !( oGClient:ConnectCoord() )

   //Capturo o Erro se a conexão não for possível

   ConOut( oGClient:GetError() )

EndIF

//Tento executar

IF !(oGClient:BatchExec("U_GMathPEnv",@aGPPEnv,"U_GMathCall",@aGPCall,"U_GMathEnd"))

//Capturo o último Erro ocorrido durante o Processamento.

ConOut( oGClient:GetError() )

EndIF

O método BatchExec espera, em seus parâmetros formais o seguinte:

BatchExec( cFnPrepEnv , aPrmPrepEnv  , cFnCallGrid , aPrmCallGrid , cFnEndGrid ):

cFnPrepEnv : Função ADVPL a ser executada para a Preparação do Ambiente

aPrmPrepEnv: Array com os Parâmetros da Função de Preparação do Ambiente

cFnCallGrid: Função ADVPL para Processamento em Grid

aPrmCallGrid: Array com os Parâmetros da Função de Processamento em Grid

cFnEndGrid: Função em ADVPL a ser executada na Finalização do Processo em Grid

GRID_CLIENT_NEWGRID_CLIENT_BATCHEXEC 

Simples assim.

E, para o “Multi Thread” também. Neste caso, usaremos a função StartJob(). StartJob possui os seguintes parâmetros formais:

StartJob( cADVPLFun , cEnvironment , lWaitRun , < [param1, …paramN] > ), onde:

cADVPLFun : Função em Advpl a ser Executada ( Obrigatório )

cEnvironmet : Ambiente a ser utilizado ( Obrigatório )

lWaitRun : Se .T. aguarda até que o processamento seja concluído e seu retorno será o retorno real da função passada como parâmetro em cADVPLFun;

< [param1, …paramN] > : Parâmetros ( Opcional ) a serem passados para a função a ser Executada conforme cADVPLFun

U_GMathIPNum() é mais rica na exploração de ambas.

Bem, agora que já vimos, através de fragmentos de código, como o “Processamento em Grid” e “Multi Thread” são via ADVPL, vamos a configuração.

Para o processo em “Multi Thread” nenhuma configuração adicional se faz necessária, mas para o “Processamento em Grid” teremos:

Grid de processamento AdvPL – Configuração (referência tdn: http://tdn.totvs.com.br/kbm#30760)

No Grid Server (Coordinator)

[ONSTART]
Jobs=GridServer
RefreshRate=60
[GridServer]
Main=GridServer
Environment=PTGrid

[GridAgent]
Main=GridAgent
AgentIp=protheus
AgentPort=4020
Instances=15
Environment=PTGrid
CoordServer=protheus
CoordPort=4020

Por Algum motivo, a configuração do GridAgent no “Coordinator” é obrigatória.

No Grid Client (Agent)

[ONSTART]
JOBS=GridAgent
RefreshRate=15


[GridAgent]
Main=GridAgent
AgentIp=protheus
AgentPort=4021
Instances=15
Environment=PTGrid
CoordServer=protheus
CoordPort=4020

Ao contrário da configuração do “Load Balance”, onde o servidor “Master” identifica os “Slaves”, no “Processamento em Grid” são os “Agentes” que se Identificam ao “Coordinator”.

Pode-se utilizar os mesmos serviços Protheus utilizados na configuração do “Load Balance” (e é recomendado) mas não necessário. Qualquer serviço protheus que se comunique com o “Coordinator” pode ser um “Agent”. Poderemos ter tantos “Agents” quantos necessários. Para testar “Números Perfeitos” usei o PC de casa. Cinco serviços do Protheus escutando nas portas 4020 a 4024 sendo:

O servidor “Principal” (Master ou Coordinator)

[ServerNetWork]
Servers=Slave01,Slave02,Slave03,Slave04
MasterConnection=0

[Slave01]
Type=TCPIP
Server=protheus
Port=4021
Connections=30

[Slave02]
Type=TCPIP
Server=protheus
Port=4022
Connections=30

[Slave03]
Type=TCPIP
Server=protheus
Port=4023
Connections=30

[Slave04]
Type=TCPIP
Server=protheus
Port=4024
Connections=30

[ONSTART]
Jobs=GridServer
RefreshRate=60
[GridServer]
Main=GridServer
Environment=PTGrid

[GridAgent]
Main=GridAgent
AgentIp=protheus
AgentPort=4020
Instances=15
Environment=PTGrid
CoordServer=protheus
CoordPort=4020

e, os Slaves ou Agents ( de 4021 a 4024 ):

[ONSTART]
JOBS=GridAgent
RefreshRate=15


[GridAgent]
Main=GridAgent
AgentIp=protheus
AgentPort=4021 ; de 4021 a 4024
Instances=15
Environment=PTGrid
CoordServer=protheus
CoordPort=4020

Feita a configuração, basta compilar os programas do exemplo e executar a função U_GMathIPNum().

Uma Dica, “Depurar” um programa “Multi Thread” não é nada fácil, mas, para ativar a “Depuração” marque, no IDE do Protheus, e para o ambiente que deseja depurar, a opção: “Permitir depuração de múltiplas threads” (Arquivo\Configuração Selecione o Ambiente, botão Editar, Aba Geral).

IDE_MTHREAD

Para que o IDE possa “capturar” uma “Thread” para “Depuração” ele precisa estar em “Modo Debug”.

IDE_DEBUG_MODE

IDE_DEBUG_MODE_IMAGE

Que é Ativado quando executamos qualquer função pelo IDE, mesmo que inválida, como, por exemplo: MsgInfo

IDE_DEBUG_MODE_MSGINFO

Para não ficar maluco, procure garantir que apenas uma “Thread” esteja ativa durante o “Processo de  Depuração”.

Para monitorar o “Processamento em Grid” use o TotvsMonitor ou o Monitor conforme instantâneo abaixo:

MONITOR

Muitas informações do “Processamento em Grid” são enviadas para o Console do Protheus e para o seu arquivo de LOG, conforme abaixo:

CONSOLE_LOG 

Considerando que para a apuração dos “Números Perfeitos” utilizamos a Classe TMathIntegerStr, se baixar os arquivos dessa classe terá, também, a última versão de “Números Perfeitos”, agora no arquivo U_GMathINPerfeito.prg. Baixe a última versão das Classes TMath[I/S]Str, compile o Projeto e execute U_GMathIPNum() para ver o funcionamento do “Processamento em Grid” e “Mult Thread” no Protheus.

Poderá obtê-la ao clicar aqui.

Post Scriptum: “Números Perfeitos”, além de uma curiosidade matemática, pode leva-lo ao “Livro dos Records”. Encontre um “Número Perfeito” com mais de 25.956.377 algarismos e seja reconhecido mundialmente. Além da curiosidade matemática e da possibilidade de torna-lo “famoso” “Números Perfeitos” pode ser útil para avaliar o desempenho dos seus servidores no que diz respeito ao uso do Protheus.

Curiosidade Matemática: Euclides e os “Números Perfeitos”

[]s
иαldσ dj

7 comentários:

  1. Parabens denovo!
    Vou aplicar este exemplo para testar o desempenho dos meus servidores.
    Estamos prestes a fazer um upgrade e sera bacana para mensurar o ganho de performance... :)
    Vlw Naldo.

    ResponderExcluir
  2. Cara, fica até chato comentar no seu blog.
    Porque sempre é para escrever a mesma coisa...

    PARABENS PELA PESQUISA, PELO APRENDIZADO E POR DIVIDIR PARA CONQUISTAR.

    Chega aí em BH e vamos tomar uma GELA e queimar umas carnes!

    GTalk!

    ResponderExcluir
  3. GTalk!!!

    Hehe, demorô!!! vamos pras brejas.....

    []s
    иαldσ dj

    ResponderExcluir
  4. Ferne$,

    Tente aumentar os valores das constantes abaixo (faça o server trabalhar) e diga-nos como o Protheus se saiu. Será que Protheus será páreo para "Números Perfeitos" ou vai pedir arrego?


    #DEFINE NP_GRID "10" //Informe um Numero Par
    #DEFINE NP_THREAD 5 //Numero de Threads Concorrentes
    #DEFINE NP_MAXZERO 25 //0000000000000000000000000 | How big do you want?
    #DEFINE NP_MAXNUMP ( NP_MAXZERO + 1 ) //10000000000000000000000000 | MASK: 10.000.000.000.000.000.000.000.000

    E.T.: Tem uma nova versão disponível para download.

    []s
    иαldσ dj

    ResponderExcluir
  5. Camo faço para baixar o exemplo U_GMathINPerfeito.prg, não esta mais disponivel

    ResponderExcluir
  6. André, é só seguir o link https://docs.google.com/leaf?id=0BxUwnVt68UewN2FjYTEyNzItZGE1ZC00NTk0LWFkYzAtYTRlODQ4MjI2MjQ1&sort=name&layout=list&num=50 ou clicar no "aqui" do post. Irá redirecionar para o Google Docs. No Lado Superior Direito da "Janela" do Browser irá aparecer um botão "Download"

    []s
    Naldo.

    P.S.: Estou pensando em reescrever Números Perfeitos e as classes matemáticas no Harbour. Usando toda técnica orientada a objeto: inclusive Sobrecarga de operadores (uma coisa que não tem no protheus)

    ResponderExcluir
  7. melhor dizendo, Advpl é que não possibilita a Sobrecarga de Operadores e muitos outros recursos de OO.

    ResponderExcluir