Antywzór: użycie właściwości WaitForComplete() w kodzie JavaScript

Przeglądasz dokumentację Apigee Edge.
Otwórz dokumentację Apigee X.
Informacje

Zasada JavaScript w Apigee Edge umożliwia dodawanie niestandardowego kodu, który jest wykonywany w kontekście przepływu serwera proxy interfejsu API. Kod niestandardowy określony w zasadzie JavaScriptu może na przykład służyć do:

  • Pobieranie i ustawianie zmiennych przepływu
  • Wykonywanie niestandardowej logiki i obsługa błędów
  • Wyodrębnianie danych z żądań lub odpowiedzi
  • Dynamiczne edytowanie docelowego adresu URL backendu
  • Dynamiczne dodawanie i usuwanie nagłówków do żądania lub odpowiedzi
  • Analizowanie odpowiedzi JSON

Klient HTTP

Przydatną funkcją zasad JavaScriptu jest klient HTTP. Klient HTTP (lub obiekt httpClient) może służyć do wykonywania jednego lub wielu wywołań usług backendu lub zewnętrznych. Klient HTTP jest szczególnie przydatny, gdy zachodzi potrzeba wykonywania wywołań wielu usług zewnętrznych i łączenia odpowiedzi w jednym interfejsie API.

Przykładowy kod JavaScript wywołujący backend z użyciem obiektu httpClient

var headers = {'X-SOME-HEADER' : 'some value' };
var myRequest = new Request("http://www.example.com","GET",headers);
var exchange = httpClient.send(myRequest);

Obiekt httpClient udostępnia 2 metody get i send (send w powyższym przykładowym kodzie) do wysyłania żądań HTTP. Obie metody są asynchroniczne i zwracają obiekt exchange przed zakończeniem rzeczywistego żądania HTTP.

Żądania HTTP mogą zająć od kilku sekund do kilku minut. Po wysłaniu żądania HTTP ważne jest, by wiedzieć, kiedy zostało ono zrealizowane – dzięki temu możliwe będzie przetworzenie odpowiedzi na żądanie. Jednym z najczęstszych sposobów określenia, czy żądanie HTTP zostało ukończone, jest wywołanie metody waitForComplete() obiektu exchange.

waitForComplete()

Metoda waitForComplete() wstrzymuje wątek do momentu zakończenia żądania HTTP i zwrócenia odpowiedzi (powodzenie/niepowodzenie). Następnie można przetworzyć odpowiedź z backendu lub usługi zewnętrznej.

Przykładowy kod JavaScript z metodą WaitForComplete()

var headers = {'X-SOME-HEADER' : 'some value' };
var myRequest = new Request("http://www.example.com","GET",headers);
var exchange = httpClient.send(myRequest);
// Wait for the asynchronous GET request to finish
exchange.waitForComplete();

// Get and Process the response
if (exchange.isSuccess()) {
    var responseObj = exchange.getResponse().content.asJSON;
    return responseObj.access_token;
} else if (exchange.isError()) {
    throw new Error(exchange.getError());
}

Antywzór

Użycie parametru waitForComplete() po wysłaniu żądania HTTP w kodzie JavaScript może mieć wpływ na wydajność.

Przeanalizujmy poniższy kod JavaScript, który wywołuje waitForComplete() po wysłaniu żądania HTTP.

Kod pliku sample.js

// Send the HTTP request
var exchangeObj = httpClient.get("http://example.com");
// Wait until the request is completed
exchangeObj.waitForComplete();
// Check if the request was successful
if (exchangeObj.isSuccess())  {

    response = exchangeObj.getResponse();
    context.setVariable('example.status', response1.status);
} else {
   error = exchangeObj.getError();
   context.setVariable('example.error', 'Woops: ' + error);
}

W tym przykładzie:

  1. Kod JavaScript wysyła żądanie HTTP do interfejsu API backendu.
  2. Następnie wywołuje metodę waitForComplete(), aby wstrzymać wykonanie żądania do momentu zrealizowania żądania.

    Interfejs waitForComplete() API powoduje, że wątek wykonujący kod JavaScript jest blokowany do czasu zakończenia przetwarzania żądania przez backend i odpowiada na nie.

Obowiązuje górny limit liczby wątków (30%), które mogą w dowolnym momencie wykonywać jednocześnie kod JavaScript w procesorze wiadomości. Po osiągnięciu limitu nie będzie dostępnych wątków do wykonania kodu JavaScript. Jeśli zbyt wiele równoczesnych żądań wykonuje interfejs waitForComplete() API w kodzie JavaScript, kolejne żądania będą kończyć się niepowodzeniem i wyświetleniem 500 wewnętrznego błędu serwera i komunikatu o błędzie „Upłynął limit czasu”, jeszcze zanim zasada JavaScript wygaśnie.

Ogólnie ten scenariusz może wystąpić, jeśli przetwarzanie żądań przez backend zajmuje dużo czasu lub gdy występuje duży ruch.

Wpływ

  1. Jeśli liczba równoczesnych żądań realizujących waitForComplete() w kodzie JavaScript przekracza zdefiniowany limit, żądania do interfejsu API kończą się niepowodzeniem i wyświetlany jest 500 wewnętrzny błąd serwera oraz komunikat o błędzie „Przekroczono limit czasu”.
  2. Zdiagnozowanie przyczyny problemu może być trudne, ponieważ JavaScript kończy się niepowodzeniem z powodu błędu „Upłynął limit czasu”, mimo że nie upłynął limit czasu dla określonej zasady JavaScript.

Sprawdzona metoda

Wywołania zwrotne w kliencie HTTP pozwalają uprościć kod objaśnienia i zwiększyć wydajność oraz uniknąć używania waitForComplete() w kodzie JavaScript. Dzięki tej metodzie wątek wykonujący JavaScript nie będzie blokowany do czasu zakończenia żądania HTTP.

W przypadku użycia wywołania zwrotnego wątek wysyła żądania HTTP w kodzie JavaScript i wraca do puli. Wątek nie jest już zablokowany, więc może obsługiwać inne żądania. Gdy żądanie HTTP zostanie zrealizowane, i wywołanie zwrotne będzie gotowe do wykonania, zostanie utworzone zadanie i dodane do kolejki zadań. Jeden z wątków z puli wykona wywołanie zwrotne na podstawie priorytetu zadania.

Przykładowy kod JavaScript z wykorzystaniem wywołań zwrotnych w httpClient

function onComplete(response,error) {
 // Check if the HTTP request was successful
    if (response) {
      context.setVariable('example.status', response.status);
     } else {
      context.setVariable('example.error', 'Woops: ' + error);
     }
}
// Specify the callback Function as an argument
httpClient.get("http://example.com", onComplete);

Więcej informacji