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

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

Политика 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 .

ожиданиеForComplete()

Метод 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() , чтобы приостановить выполнение до завершения запроса.

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

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

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

Влияние

  1. Запросы API завершатся с ошибкой 500 Internal Server Error и с сообщением об ошибке «Время ожидания истекло», когда количество одновременных запросов, выполняющих 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);

Дальнейшее чтение