Artigo
· jan 25 3min de leitura

Como contornar o tempo limite de serviços SOAP

Alguns dos nossos aplicativos oferecem serviços SOAP que usam consultas SQL baseadas em "DSTIME" que retornam registros que foram adicionados ou alterados recentemente. Como os registros não mudam com frequência, essas consultas geralmente retornam uma quantidade pequena de registros e, por isso, levam pouco tempo.

No entanto, às vezes fazemos uma alteração em uma tabela que afeta todos os registros nela. Quando isso acontece, na próxima solicitação SOAP de um cliente SOAP, o serviço executará sua consulta, que levará bem mais tempo, porque todos os registros são incluídos (para nossos apps, as consultas retornam centenas de milhares de registros nesse caso).

A quantidade de tempo que leva para produzir os resultados, portanto, às vezes excede o "tempo limite" padrão especificado na conexão do CSP gateway para a instância que hospeda o serviço SOAP. Isso faz com que a conexão seja encerrada antes que o cliente receba os dados solicitados e, em vez disso, aparece uma mensagem de erro assim:

ERROR #5002: ObjectScript error: InvokeClient+208^%SOAP.WebClient.1

Podemos confirmar que o erro se deve a um tempo limite ao visualizar os detalhes do erro no cliente usando o recurso "InterSystems IRIS SOAP Log" descrito aqui.

A saída a seguir do arquivo de log confirma o erro de tempo limite:

Input to Web client with SOAP action = http://www.intersystems.com/user/SOAPTest.SlowSOAPService.GetSlowService

ERROR #5922: Timed out waiting for response
string**** SOAP client return error. method=GetSlowService, action=http://www.intersystems.com/user/SOAPTest.SlowSOAPService.GetSlowService
     ERROR #5922: Timed out waiting for response

Para resolver esse erro, adicionamos código para definir um tempo limite de conexão para a instância do cliente SOAP antes de chamar o método SOAP que usa essa consulta. Tivemos que executar a consulta na página SQL do Portal de Gerenciamento, gravando a saída em um arquivo csv, o que levou mais de 6 minutos para ser concluído. Portanto, adicionamos esse código para aumentar o tempo limite para 10 minutos antes de chamar o serviço (os nomes foram alterados para proteger os inocentes 😊):

    #dim result As %XML.DataSet
    set wc = ##class(SlowSOAPService.WebClient.SlowSOAPServiceSoap).%New()
    set sc = wc.TimeoutSet(600)
    set sc = wc.GetSlowService(.result)

A classe %SOAP.WebService fornece o método "TimeoutSet", que só muda o valor de tempo limite da conexão para essa solicitação. Isso não afeta o valor de tempo limite da conexão do CSP gateway, que, por padrão, é apenas 30 segundos (para incentivar a escrita de código do lado do servidor eficiente).

Para manter esse incentivo, podemos garantir que o tempo limite prolongado só seja usado em casos raros necessários ao envolver o código do cliente em código condicional que verifica um global, da seguinte maneira:

    #dim result As %XML.DataSet
    set wc = ##class(SlowSOAPService.WebClient.SlowSOAPServiceSoap).%New()
    if (^reallySlowSvcExpectedTime > 0) {
        set sc = wc.TimeoutSet(^reallySlowSvcExpectedTime)
    }
    set sc = wc.GetSlowService(.result)

O global age como uma sinalização (maior que 0? Defina o tempo limite) e o número de segundos de espera. Para o problema descrito no início deste artigo, avisaríamos os clientes que eles devem definir temporariamente um global usando um terminal do IRIS conectado à instância da seguinte maneira:

    set ^reallySlowSvcExpectedTime = 600

Novamente, esperamos que o serviço retorne uma quantidade pequena de dados com rapidez, e os clientes podem ser redefinidos para o uso do tempo limite padrão ao definir o global de novo como 0:

    set ^reallySlowSvcExpectedTime = 0
Discussão (0)1
Entre ou crie uma conta para continuar