الگوی بد: استفاده از waitForComplete() در کد جاوا اسکریپت

درحال مشاهده اسناد Apigee Edge هستید.
به اسناد Apigee X بروید.
اطلاعات

خط‌مشی جاوا اسکریپت در Apigee Edge به شما امکان می‌دهد کد سفارشی‌ای اضافه کنید که در بافت جریان پراکسی API اجرا می‌شود. برای مثال، از کد سفارشی در خط‌مشی جاوا اسکریپت می‌توان برای موارد زیر استفاده کرد:

  • دریافت و تنظیم متغیرهای جریان
  • اجرای منطق سفارشی و انجام مدیریت خطا
  • استخراج داده‌ها از درخواست‌ها یا پاسخ‌ها
  • نشانی وب هدف زیرینه را به‌صورت پویا ویرایش کنید
  • به‌صورت پویا سرصفحه‌ها را به درخواست یا پاسخ اضافه کنید یا از آن بردارید
  • تجزیه پاسخ JSON

کارخواه HTTP

یکی از ویژگی‌های قدرتمند خط‌مشی جاوا اسکریپت، کارخواه HTTP است. از کارخواه HTTP (یا شیء httpClient) می‌توان برای برقراری یک یا چند تماس با سرویس‌های خارجی یا زیرینه استفاده کرد. کارخواه HTTP به‌ویژه زمانی مفید است که نیاز به برقراری تماس با چندین سرویس خارجی و ترکیب پاسخ‌ها در یک API واحد وجود داشته باشد.

نمونه کد جاوا اسکریپت که با شیء 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 آشکار می‌کند. هر دو روش ناهمزمان هستند و قبل‌از تکمیل درخواست واقعی HTTP، یک شیء exchange برمی‌گردانند.

درخواست‌های HTTP ممکن است چند ثانیه تا چند دقیقه طول بکشند. پس‌از انجام درخواست HTTP، مهم است بدانید که چه زمانی تکمیل می‌شود تا پاسخ درخواست بتواند پردازش شود. یکی از رایج‌ترین روش‌ها برای تعیین زمان تکمیل درخواست HTTP، فراخوانی روش waitForComplete() شیء exchange است.

waitForComplete()

روش waitForComplete() رشته را تا زمانی که درخواست HTTP تکمیل شود و پاسخی (موفقیت/شکست) برگردانده شود، متوقف می‌کند. سپس، پاسخ سرویس خارجی یا زیرینه می‌تواند پردازش شود.

نمونه کد جاوا اسکریپت با 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 زیر را که پس‌از ارسال درخواست HTTP، waitForComplete() را فرا می‌خواند درنظر بگیرید.

کد برای 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. کد جاوا اسکریپت درخواست HTTP را به یک API زیرینه ارسال می‌کند.
  2. سپس waitForComplete() را فرا می‌خواند تا اجرا را تا زمان تکمیل درخواست متوقف کند.

    waitForComplete() API باعث می‌شود رشته‌ای که کد جاوااسکریپت را اجرا می‌کند تا زمانی‌که زیرینه پردازش درخواست را تکمیل کند و پاسخ دهد مسدود شود.

محدودیت بالایی برای تعداد رشته‌هایی (۳۰٪) که می‌توانند به‌طور هم‌زمان کد جاوا اسکریپت را در «پردازنده پیام» اجرا کنند وجود دارد. پس‌از رسیدن به این حد مجاز، هیچ رشته‌ای برای اجرای کد JavaScript دردسترس نخواهد بود. بنابراین، اگر درخواست‌های هم‌زمان زیادی درحال اجرای waitForComplete() API در کد JavaScript باشند، درخواست‌های بعدی با پیام خطای 500 Internal Server Error و «Timed out» ناموفق خواهند بود، حتی قبل‌از اینکه خط‌مشی JavaScript منقضی شود.

به‌طورکلی، این سناریو ممکن است زمانی رخ دهد که پردازش درخواست‌ها در زیرینه زمان زیادی طول بکشد یا ترافیک بالا باشد.

تأثیر

  1. وقتی تعداد درخواست‌های هم‌زمان درحال اجرا waitForComplete() در کد JavaScript از حد ازپیش تعریف‌شده فراتر رود، درخواست‌های API با خطای سرور داخلی ۵۰۰ و با پیام خطای «مهلت زمانی تمام شد» ناموفق خواهد بود.
  2. تشخیص علت مشکل می‌تواند دشوار باشد زیرا جاوا اسکریپت با خطای «زمان پایان یافت» ازکار می‌افتد، حتی اگر محدودیت زمانی برای خط‌مشی جاوا اسکریپت خاص سپری نشده باشد.

روال مطلوب

از برگشتی‌ها در کارخواه HTTP برای ساده‌سازی کد تماس بیرونی و بهبود عملکرد استفاده کنید و از waitForComplete() در کد جاوا اسکریپت استفاده نکنید. این روش تضمین می‌کند که رشته‌ای که JavaScript را اجرا می‌کند تا زمانی که درخواست HTTP تکمیل شود مسدود نمی‌شود.

وقتی از تماس برگشتی استفاده می‌شود، رشته درخواست‌های HTTP را در کد جاوا اسکریپت ارسال می‌کند و به استخر برمی‌گردد. ازآنجایی‌که رشته دیگر مسدود نیست، برای رسیدگی به درخواست‌های دیگر دردسترس است. پس‌از تکمیل درخواست HTTP و آماده شدن برگشت تماس برای اجرا، تکلیفی ایجاد و به صف تکلیف اضافه خواهد شد. یکی از رشته‌های استخر براساس اولویت تکلیف، تماس برگشتی را اجرا خواهد کرد.

نمونه کد جاوا اسکریپت بااستفاده از «بازخوان‌ها» در 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);

مطالعه بیشتر