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

כרגע מוצג התיעוד של Apigee Edge.
כניסה למסמכי התיעוד של Apigee X.
מידע

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

  • קבלה והגדרה של משתני זרימה
  • הפעלת לוגיקה מותאמת אישית וטיפול בכשלים
  • חילוץ נתונים מבקשות או מתשובות
  • עריכה דינמית של כתובת היעד של הקצה העורפי
  • הוספה או הסרה דינמית של כותרות לבקשה או לתגובה
  • ניתוח של תגובת 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 היא להפעיל את השיטה 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 גורם לחסימה של ה-thread שמריץ את קוד ה-JavaScript עד להשלמת עיבוד הבקשה בקצה העורפי.

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

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

השפעה

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

שיטה מומלצת

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

כאשר נעשה שימוש בקריאה חוזרת, ה-thread שולח את בקשות ה-HTTP בקוד ה-JavaScript וחוזר למאגר. השרשור כבר לא חסום, כך שהוא זמין לטיפול בבקשות אחרות. לאחר השלמת בקשת ה-HTTP והקריאה החוזרת מוכנה לביצוע, תיווצר משימה שתתווסף לתור המשימות. אחד מה-threads מהמאגר יבצע את הקריאה החוזרת (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);

קריאה נוספת