Antipattern: שימוש ב-waitForcomplete() בקוד JavaScript

אתם צופים במסמכי התיעוד של Apigee Edge.
עוברים אל מסמכי תיעוד של Apigee X.
מידע

מדיניות JavaScript ב-Apigee Edge מאפשרת להוסיף קוד מותאם אישית שמופעל בהקשר של תהליך API לשרת proxy. לדוגמה, אפשר להשתמש בקוד המותאם אישית במדיניות JavaScript כדי:

  • קבלה והגדרה של משתני זרימה
  • הפעלת לוגיקה מותאמת אישית וטיפול בתקלות
  • חילוץ נתונים מבקשות או מתגובות
  • עריכה דינמית של כתובת ה-URL של היעד של הקצה העורפי
  • הוספה או הסרה של כותרות באופן דינמי מבקשה או מתשובה
  • ניתוח תגובת JSON

לקוח HTTP

לקוח HTTP הוא תכונה יעילה מאוד במדיניות JavaScript. אפשר להשתמש בלקוח ה-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 מסתיימת היא הפעלת ה-method waitForComplete() של האובייקט exchange.

waitForComplete()

ה-method waitForComplete() משהה את השרשור עד להשלמת בקשת ה-HTTP ומוחזרת תגובה (הצלחה/כשל). לאחר מכן, ניתן לעבד את התשובה מקצה עורפי או משירות חיצוני.

קוד JavaScript לדוגמה עם pendingForcomplete()

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 והודעת השגיאה 'התוקף פג', עוד לפני שהתוקף של מדיניות JavaScript יפוג.

באופן כללי, תרחיש זה עשוי להתרחש אם לקצה העורפי נדרש זמן רב לעיבוד בקשות או אם יש תנועה רבה.

השפעה

  1. בקשות ה-API ייכשלו ויתקבלו 500 שגיאת שרת פנימית ועם הודעת השגיאה 'תם הזמן הקצוב לתפוגה'. כאשר מספר הבקשות בו-זמניות שמבצעות את waitForComplete() בקוד JavaScript חורג מהמגבלה המוגדרת מראש.
  2. אבחון הגורם לבעיה עשוי להיות מורכב, כי קוד ה-JavaScript נכשל עם 'תם הזמן הקצוב לתפוגה'. שגיאה על אף שמגבלת הזמן עבור מדיניות JavaScript הספציפית לא חלפה.

שיטה מומלצת

כדאי להשתמש בקריאות חוזרות (callback) בלקוח ה-HTTP כדי לייעל את קוד היתרונות המרכזיים, לשפר את הביצועים ולהימנע משימוש ב-waitForComplete() בקוד JavaScript. השיטה הזו מבטיחה שהשרשור שמפעיל JavaScript לא יהיה חסום עד להשלמת בקשת ה-HTTP.

כשמשתמשים בקריאה חוזרת (callback), ה-thread שולח את בקשות ה-HTTP בקוד ה-JavaScript וחוזר למאגר. השרשור כבר לא חסום, ולכן אפשר לטפל בבקשות אחרות. אחרי ש-HTTP request יושלם והקריאה החוזרת (callback) תהיה מוכנה לביצוע, תיווצר משימה ותתווסף לתור המשימות. אחד מהשרשורים מהמאגר יבצע את הקריאה החוזרת על סמך רמת העדיפות של המשימה.

קוד JavaScript לדוגמה באמצעות קריאות חוזרות (callbacks) ב-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);

קריאה נוספת