Gestão de Processos Assíncronos
As parametrizações descritas neste manual terão impacto nas operações mencionadas na documentação da tela Consulta de Requisições (F660REQ). Estas configurações permitem que o ERP gerencie a execução de processos assíncronos, controlando o número de requisições enviadas ao middleware.
- Seniorconfigcenter: em Middleware -> Web 5.0 -> Processos automáticos, habilite a opção "Habilitar agendador de processos automáticos".
- F000PGS: através do parâmetro global QtdLimReq, defina o limite máximo de requisições em processamento no middleware.
- F000AGE: cadastre um processo automático do tipo Rotina com o código "Rotina Sapiens" = 173 e, no botão Agendar, especifique a frequência de atualização da fila de execução.
- Exemplo:
- Execução da integração contábil mensal (30 dias), com requisições diárias.
Parâmetro QtdLimReg = 10
Periodicidade do processo automático = Hora - Neste cenário, serão criadas 30 requisições para serem enviadas ao middleware.
- Apenas serão executadas, no máximo, 10 requisições simultaneamente, conforme definido no parâmetro global. As demais permanecerão em fila de espera para execução.
- De acordo com a periodicidade do processo automático, a cada hora o ERP verificará quantos processos estão em execução no momento. Caso este número seja menor que a quantidade definida no parâmetro global, o sistema iniciará a execução de outros processos que estavam na fila de espera, até alcançar o limite estabelecido. Ou seja, se estiverem sendo executados apenas 8 processos, serão iniciados mais 2. Atualmente, a gestão da fila de execução não considera a quantidade de instâncias disponíveis, mas apenas o valor definido no parâmetro global.
- No log do processo agendado, serão exibidas as seguintes informações:
- Quantidade de instâncias configuradas no parâmetro global QtdLimReq
- Quantidade de requisições em processamento
- Quantidade de requisições enviadas
- A gestão dessa fila de execução permanece ativa enquanto houver requisições pendentes.
- Execução da integração contábil mensal (30 dias), com requisições diárias.
- F660REQ: Esta tela permite consultar o plano de execução e o status de cada processo. Além disso, possibilita o cancelamento ou a priorização de requisições que estejam na fila para execução.
Fluxograma do processo
Gerenciamento assíncrono de web services customizados
A fim de contemplar os novos recursos do gerenciador de requisições assíncronas, foram desenvolvidas funções para programadores, de modo a permitir a execução de web services customizados a partir dele
Funções
AgendarExecucaoWebservice
Permitir que o usuário insira um novo web services na fila de gerenciamento de requisições
Sintaxe
AgendarExecucaoWebservice(Numero pCodEmp, Alfa pAbrFil, Alfa pWebService, Alfa pPorta, Alfa pJSON);
Parâmetros:
| Nome | Tipo | Descrição |
|---|---|---|
|
pCodEmp |
Número |
Código da empresa que será gravado na E000PLE |
|
pAbrFil |
Alfa |
Abrangência de filiais que será gravado na E000PLE |
|
pWebService |
Alfa |
Caminho do webservice que será executado. Ex: com.senior.g5.co.mct.ctb.integracao |
|
pPorta |
Alfa |
Porta do webservice que será executado. Ex: Integrar_8 |
|
pJson |
Alfa |
JSON contendo o nome dos parâmetros e seus respectivos valores |
Observação
É de extrema importância que os parâmetros enviados no JSON representem uma requisição única. Caso seja enviada uma requisição com parâmetros e valores IGUAIS, e exista uma requisição com os mesmos parâmetros na fila para envio, o sistema cancelará a requisição anterior e executará apenas a última que foi enviada.
AgendarExecucaoWebserviceEx
Sintaxe:AgendarExecucaoWebserviceEx(Numero pCodEmp, Alfa pAbrFil, Alfa pWebService, Alfa pPorta, Alfa pJSON, Numero End pIdePle)
Parâmetros:
| Nome | Tipo | Descrição |
|---|---|---|
| pCodEmp | Numero | Código da empresa que será gravado na E000PLE |
| pAbrFil | Alfanumérico | Abrangência de filiais que será gravado na E000PLE |
| pWebService | Alfanumérico | Caminho do web services que será executado. Ex: com.senior.g5.co.mct.ctb.integracao |
| pPorta | Alfanumérico | Porta do web services que será executado. Ex: Integrar_8 |
| pJson | Alfanumérico | JSON contendo o nome dos parâmetros e seus respectivos valores |
| pIdePle | Alfanumérico | Código identificador da requisição gerada (E000PLE.IDEUNI) |
Observação
É de extrema importância que os parâmetros enviados no JSON representem uma requisição única. Caso seja enviada uma requisição com parâmetros e valores IGUAIS, e exista uma requisição com os mesmos parâmetros na fila para envio, o sistema cancelará a requisição anterior e executará apenas a última que foi enviada.
AlterarStatusPlanoExecucao
Sintaxe: alterarStatusPlanoExecucao(Numero pIdePle, Numero pStsReq);
Parâmetros:
| Nome | Tipo | Descrição |
|---|---|---|
|
pIdePle |
Numero |
Identificador do plano de execução. |
|
pStsReq |
Numero |
Status da requisição:
Somente permite alterar o status para 2 - Em andamento ou 3 - Finalizado
|
InserirPassoPlanoExecucao
Sintaxe:InserirPassoPlanoExecucao(Numero pIdePle; alfa pMensagem)
Parâmetros:
| Nome | Tipo | Descrição |
|---|---|---|
| pIdePle | Numero | Código do identificador do plano de execução (E000PLE.IDEUNI) |
| pMensagem | Alfanumérico | Mensagem a ser exibida no detalhamento do processo |
JSON
O uso do formato JSON para os campos é o padrão adotado; é um modelo de estrutura de pares chave-valor, sendo um formato de dados mais conciso e de fácil interpretação. Um exemplo de modelo no formato XML seria:
<user> |
O modelo JSON seria representado da seguinte forma:
{
"user": {
"id": "11",
"animal": "Bob",
"idade": “2”
}
}
|
Exemplo de uso:
Para exemplificar como utilizar o recurso, teremos uma regra em LSP que irá buscar de uma tabela de usuário, pedidos para serem integrados em um web services customizado.
Regra
Para o exemplo abaixo, selecionamos todos os pedidos que existem na tabela de usuários USU_TPROCESSOS, que estão com status (USU_STATUS) pendente (P). Após agendar a execução no web services, retornamos o identificador da requisição gerada, para que, no web services, possamos processar os pedidos daquele lote. Sendo assim, é realizado o update na USU_TPROCESSOS, passando o identificador para os pedidos selecionados.
Definir Alfa xSQL;
Definir Alfa xIdentificador;
Definir Alfa xCur_Pedidos;
Definir Numero xQtdPendente;
Definir Alfa xIdentificadores;
Definir Alfa xIdentificadoresJSON;
Definir Alfa xJSON;
Definir Numero xQtdPedidosEnviar;
Definir Alfa xAbrFil;
Definir Numero xTamanho;
Definir Numero xErro;
Definir Alfa xMensagemErro;
Definir numero xIdePle;
Definir alfa aIdePle;
xIdentificadores = "";
xIdentificadoresJSON = "";
IntParaAlfa(CodFil, xAbrFil);
xQtdPedidosEnviar = 0;
xSQL = "SELECT USU_IDENTF, USU_DATGER FROM USU_TPROCESSOS WHERE USU_TIPPROC =
'P' AND USU_STATUS = 'P' ORDER BY USU_DATGER";
SQL_Criar(xCur_Pedidos);
SQL_DefinirComando(xCur_Pedidos, xSQL);
SQL_AbrirCursor(xCur_Pedidos);
/* Irá retornar todos os pedidos com status pendente de importação */
Enquanto (SQL_EOF(xCur_Pedidos) = 0)
Inicio
SQL_RetornarAlfa(xCur_Pedidos, "USU_IDENTF", xIdentificador);
xIdentificadores = xIdentificadores + "'" + xIdentificador + "',";
xIdentificadoresJSON = xIdentificadoresJSON + xIdentificador + ",";
xQtdPedidosEnviar++;
Se (xQtdPedidosEnviar = 3)
Inicio
/* Aqui removemos a ultima virgula na string que serão os parâmetros, nesse caso não
seria necessário utilizar os identificadores como parâmetros */
/* mas estou informando para manter a unicidade da requisição */
TamanhoAlfa(xIdentificadores, xTamanho);
xTamanho--;
CopiarStr(xIdentificadores, 1, xTamanho);
TamanhoAlfa(xIdentificadoresJSON, xTamanho);
xTamanho--;
CopiarStr(xIdentificadoresJSON, 1, xTamanho);
/* Parametros que são enviados para o webservice PS: DEVE ter o mesmo nome do
parâmetro do WS */
xJSON = "{\"Identificadores\": \""+xIdentificadoresJSON+"\"}";
/* Gera a requisição que será enviada pro gerenciador assíncrono executar */
AgendarExecucaoWebserviceEx(CodEmp, xAbrFil, "ainternal.custom.pedido.integrar",
"executar", xJSON, xIdePle);
IntParaAlfa(xIdePle, aIdePle);
xSQL = "UPDATE USU_TPROCESSOS SET USU_IDEPLE = "+aIdePle+" WHERE USU_IDENTF in
("+xIdentificadores+")";
ExecSQLEX(xSQL, xErro, xMensagemErro);
xQuantidadeRequisicoesGerar--;
xQtdPedidosEnviar = 0;
xIdentificadores = "";
xIdentificadoresJSON = "";
Fim;
SQL_Proximo(xCur_Pedidos);
Se ((SQL_EOF(xCur_Pedidos) <> 0) e (xQtdPedidosEnviar > 0))
Inicio
TamanhoAlfa(xIdentificadores, xTamanho);
xTamanho--;
CopiarStr(xIdentificadores, 1, xTamanho);
TamanhoAlfa(xIdentificadoresJSON, xTamanho);
xTamanho--;
CopiarStr(xIdentificadoresJSON, 1, xTamanho);
/* Parametros que são enviados para o webservice PS: DEVE ter o mesmo nome do
parâmetro do WS */
xJSON = "{\"Identificadores\": \""+xIdentificadoresJSON+"\"}";
/* Gera a requisição que será enviada pro gerenciador assíncrono executar */
AgendarExecucaoWebserviceEx(CodEmp, xAbrFil, "", "", xJSON, xIdePle);
ExecSQLEX("UPDATE USU_TPROCESSOS SET USU_IDEPLE = :xIdePle WHERE USU_IDENTF in
(:xIdentificadores)", xErro, xMensagemErro);
xQtdPedidosEnviar = 0;
xIdentificadores = "";
xIdentificadoresJSON = "";
Fim;
Fim;
SQL_FecharCursor(xCur_Pedidos);
SQL_Destruir(xCur_Pedidos);
|
Web services customizado
Ainternal.custom.pedido.integrar
Neste web services, iremos retornar todos os pedidos da tabela USU_TPROCESSOS que têm o campo USU_IDEPLE igual ao identificador da requisição que será executada. Assim, serão retornados todos os pedidos para integração que pertencem a essa requisição
definir alfa xIdentificador; definir numero xQuantidade; definir numero xLinhaAtual; Definir alfa xMensagemErro; definir alfa xCursorDados; Definir Numero xErro; Definir Numero nIdentificador; Definir Alfa xStatus; Definir Alfa xIdePle; Definir Numero nIdePle; Definir Alfa xSQL; Definir Alfa xCursor; Definir alfa xMensagem; definir interno.com.senior.g5.co.mcm.ven.pedidos.GravarPedidos_13 wsped; nIdePle = executar.IdePle; IntParaAlfa(nIdePle, xIdePle); xLinhaAtual = 0; /* Altera o status da requisição pra Em Andamento, permitindo que saia da fila de execução */ AlterarStatusPlanoExecucao(nIdePle, 2); /* Altera o status na tabela de pedido indicando que os pedidos estão em processamento */ xSQL = "UPDATE USU_TPROCESSOS SET USU_STATUS = 'EP', USU_DATINI = GETDATE() WHERE USU_IDEPLE = "+ xIdePle; ExecSQLEX(xSQL, xErro, xMensagemErro); /* Recupera todos os pedidos que serão processados naquela requisição */ xSQL = "SELECT * FROM USU_TPROCESSOS WHERE USU_IDEPLE = " +xIdePle; SQL_Criar(xCursor); SQL_DefinirComando(xCursor, xSQL); SQL_AbrirCursor(xCursor); /* Adicionar um passo de execução do pedido que está sendo integrado */ InserirPassoPlanoExecucao(nIdePle, "Carregando pedidos..."); Enquanto (SQL_EOF(xCursor) = 0) inicio /* Adiciona na grid do WS interno os pedidos que serão integrados */ SQL_RetornarAlfa(xCursor, "USU_IDENTF", xIdentificador); wsped.Pedido.CriarLinha(); wsped.Pedido.opeExe = "1"; wsped.Pedido.CodEmp = 1; wsped.Pedido.CodFil = 1; wsped.Pedido.NumPed = 5; wsped.Pedido.IdeExt = xIdentificador; xLinhaAtual++; SQL_Proximo(xCursor); fim; SQL_FecharCursor(xCursor); SQL_Destruir(xCursor); Se (wsped.Pedido.QtdLinhas > 0) Inicio /* Adicionar um passo de execução do pedido que está sendo integrado */ InserirPassoPlanoExecucao(nIdePle, "Executando importação do pedido"); wsped.modoExecucao = 1; wsped.executar(); xLinhaAtual = 0; xQuantidade = wsped.respostaPedido.QtdLinhas; Enquanto (xLinhaAtual < xQuantidade) Inicio wsped.respostaPedido.LinhaAtual = xLinhaAtual; nIdentificador = wsped.respostaPedido.IdeExt; IntParaAlfa(nIdentificador, xIdentificador); Se (wsped.respostaPedido.tipRet = 1) Inicio xMensagem = "Pedido id "+ xIdentificador+" importado com sucesso"; /* Adicionar um passo de execução do pedido que está sendo integrado */ InserirPassoPlanoExecucao(nIdePle, xMensagem); xStatus = "C"; xMensagemErro = "OK"; Fim Senao Inicio xStatus = "E"; xMensagem = "Pedido id "+ xIdentificador+" importado com erro. Mensagem: " + wsped.respostaPedido.retorno; /* Adicionar um passo de execução do pedido que está sendo integrado */ InserirPassoPlanoExecucao(nIdePle, xMensagem); Fim; xSQL = "UPDATE USU_TPROCESSOS SET USU_STATUS = :xStatus, USU_DATINI = GETDATE(), USU_MSGLOG = :xMensagemErro WHERE USU_IDEPLE =" + xIdentificador; ExecSQLEX(xSQL, xErro, xMensagemErro); xLinhaAtual++; Fim; Fim; /* Altera o status da requisição pra Finalizado */ AlterarStatusPlanoExecucao(nIdePle, 3); |
English
Español
English
Español


