Антипаттерн: используйте waitForComplete() в коде JavaScript.

Вы просматриваете документацию Apigee Edge .
Перейдите в документацию Apigee
X.info

Политика JavaScript в Apigee Edge позволяет добавлять пользовательский код, который выполняется в контексте потока API-прокси. Например, пользовательский код в политике JavaScript может использоваться для:

  • Получение и установка переменных потока
  • Выполнить пользовательскую логику и обработать ошибки.
  • Извлечение данных из запросов или ответов
  • Динамическое редактирование целевого URL-адреса бэкэнда
  • Динамическое добавление или удаление заголовков из запроса или ответа.
  • Анализ JSON-ответа

HTTP-клиент

Мощной особенностью политики JavaScript является HTTP-клиент . HTTP-клиент (или объект httpClient ) может использоваться для выполнения одного или нескольких вызовов к бэкэнду или внешним сервисам. HTTP-клиент особенно полезен, когда необходимо выполнить вызовы к нескольким внешним сервисам и объединить ответы в одном API.

Пример кода JavaScript, выполняющего вызов к бэкэнду с использованием объекта httpClient.

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

Объект httpClient предоставляет два метода: get и send (в приведенном выше примере кода используется send ) для выполнения HTTP-запросов. Оба метода являются асинхронными и возвращают объект exchange до завершения фактического HTTP-запроса.

HTTP-запросы могут занимать от нескольких секунд до нескольких минут. После отправки HTTP-запроса важно знать, когда он завершен, чтобы можно было обработать ответ. Один из наиболее распространенных способов определить, когда HTTP-запрос завершен, — это вызвать метод waitForComplete() объекта exchange .

waitForComplete()

Метод waitForComplete() приостанавливает поток до завершения HTTP-запроса и получения ответа (успех/неудача). После этого можно обработать ответ от бэкэнда или внешнего сервиса.

Пример кода JavaScript с использованием функции 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());
}

Антипаттерн

Использование waitForComplete() после отправки HTTP-запроса в коде JavaScript может негативно сказаться на производительности.

Рассмотрим следующий код JavaScript, который вызывает waitForComplete() после отправки HTTP-запроса.

Код для файла 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);
}

В этом примере:

  1. Код JavaScript отправляет HTTP-запрос к бэкэнд-API.
  2. Затем вызывается waitForComplete() , который приостанавливает выполнение до завершения запроса.

    Функция waitForComplete() в API блокирует поток, выполняющий код JavaScript, до тех пор, пока бэкэнд не завершит обработку запроса и не отправит ответ.

Существует верхний предел количества потоков (30%), которые могут одновременно выполнять код JavaScript в обработчике сообщений. После достижения этого предела потоки для выполнения кода JavaScript станут недоступны. Таким образом, если слишком много одновременных запросов выполняют API waitForComplete() в коде JavaScript, то последующие запросы завершатся ошибкой 500 Internal Server Error и сообщением об ошибке «Timed out» еще до истечения тайм-аута политики JavaScript.

Как правило, подобная ситуация может возникнуть, если бэкэнд долго обрабатывает запросы или наблюдается высокая загрузка сети.

Влияние

  1. Запросы к API завершатся ошибкой 500 Internal Server Error . Ошибка «Timed out» возникает, когда количество одновременных запросов, выполняющих waitForComplete() в коде JavaScript, превышает заданный лимит.
  2. Диагностика причины проблемы может быть сложной, поскольку JavaScript выдает ошибку «Время ожидания истекло», даже если лимит времени для конкретной политики JavaScript еще не истек.

Передовая практика

Используйте коллбэки в HTTP-клиенте для оптимизации кода обработки запросов и повышения производительности, а также избегайте использования waitForComplete() в коде JavaScript. Этот метод гарантирует, что поток, выполняющий JavaScript, не будет заблокирован до завершения HTTP-запроса.

При использовании функции обратного вызова поток отправляет HTTP-запросы в коде JavaScript и возвращается в пул. Поскольку поток больше не заблокирован, он может обрабатывать другие запросы. После завершения HTTP-запроса и готовности функции обратного вызова к выполнению создается задача, которая добавляется в очередь задач. Один из потоков из пула выполнит функцию обратного вызова в зависимости от приоритета задачи.

Пример кода JavaScript с использованием коллбэков в 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);

Дополнительная информация