בדף הזה מוסבר איך ליצור משימות ולהוסיף אותן לתורים של הודעות Push. כשרוצים לעבד משימה, צריך ליצור אובייקט משימה חדש ולהציב אותו בתור. אתם יכולים לציין במפורש את השירות ואת ה-handler שמטפלים במשימה, ואם רוצים, להעביר ל-handler נתונים ספציפיים למשימה. אפשר גם לכוונן את ההגדרות של המשימה, למשל לתזמן מועד עתידי לביצוע שלה או להגביל את מספר הפעמים שבהן המשימה תנסה להתבצע מחדש אם היא תיכשל.
יצירת משימה חדשה
כדי ליצור משימה ולהוסיף אותה לתור, קוראים לפונקציה taskqueue.Add.
import("google.golang.org/appengine/v2/taskqueue")
ציון שירות העובדים
כשמשימה יוצאת מהתור שלה, שירות תור המשימות שולח אותה לשירות של עובד. לכל משימה יש יעד וכתובת URL, שקובעים איזה שירות ומטפל יבצעו בסופו של דבר את המשימה.
target
היעד מציין את השירות שיקבל את בקשת ה-HTTP כדי לבצע את המשימה. זוהי מחרוזת שמציינת שירות/גרסה/מופע באחד מהפורמטים הקנוניים. הטפסים הכי נפוצים הם:
service
version.service
instance.version.service
מחרוזת היעד מתווספת לפני שם הדומיין של האפליקציה. יש שלוש דרכים להגדיר את היעד למשימה:
מצהירים על היעד כשיוצרים את המשימה. אפשר להגדיר את היעד באופן מפורש כשיוצרים את האובייקט Task על ידי הגדרת הכותרת
Host:כשמגדירים תור ב-
queue.yaml, צריך לכלול הנחייתtarget, כמו בהגדרה שלqueue-blue. כל המשימות שנוספו לתור עםtargetישתמשו ביעד הזה, גם אם הוקצה למשימה יעד אחר בזמן היצירה.אם לא מצוין יעד באף אחת משתי השיטות הקודמות, היעד של המשימה הוא הגרסה של השירות שמוסיפה אותה לתור. שימו לב: אם מוסיפים משימה לתור משירות ברירת המחדל ומגרסת ברירת המחדל באופן הזה, וגרסת ברירת המחדל משתנה לפני שהמשימה מופעלת, היא תופעל בגרסת ברירת המחדל החדשה.
url
url בוחר באחד מהמטפלים בשירות היעד, שיבצע את המשימה.
הערך url צריך להתאים לאחת מתבניות כתובות ה-URL של ה-handler בשירות היעד. הפרמטר url יכול לכלול פרמטרים של שאילתה אם השיטה שצוינה במשימה היא GET או PULL. אם לא מציינים url, נעשה שימוש בכתובת ה-URL שמוגדרת כברירת מחדל /_ah/queue/[QUEUE_NAME], כאשר [QUEUE_NAME] הוא שם התור של המשימה.
העברת נתונים אל ה-handler
אפשר להעביר נתונים ל-handler כפרמטרים של שאילתה בכתובת ה-URL של המשימה, אבל רק אם השיטה שצוינה במשימה היא GET או PULL.
לפונקציה NewPOSTTask יש ארגומנט תלוי מיקום בשביל query_data. הנתונים הם בדרך כלל מילון של צמדי מפתח/ערך. אם השיטה של המשימה היא POST או PUT, הנתונים מתווספים למטען הייעודי (payload) של בקשת ה-HTTP. אם השיטה היא GET, הפרמטרים מתווספים לכתובת ה-URL כפרמטרים של שאילתה.
מתן שם למשימה
כשיוצרים משימה חדשה, App Engine מקצה למשימה שם ייחודי כברירת מחדל. עם זאת, אתם יכולים להקצות שם משלכם למשימה באמצעות הפרמטר name. יתרון בהקצאת שמות משלכם למשימות הוא שהמערכת מסירה כפילויות של משימות עם שמות, כך שאתם יכולים להשתמש בשמות משימות כדי להבטיח שמשימה תתווסף רק פעם אחת. הסרת הכפילויות נמשכת 9 ימים אחרי שהמשימה מסתיימת או נמחקת.
שימו לב: לוגיקת ביטול הכפילויות יוצרת תקורה משמעותית בביצועים, וכתוצאה מכך עלייה בזמני האחזור ועלייה פוטנציאלית בשיעורי השגיאות שקשורים למשימות עם שמות. העלויות האלה יכולות להיות גבוהות במיוחד אם שמות המשימות הם עוקבים, כמו חותמות זמן. לכן, אם אתם מקצים שמות משלכם, מומלץ להשתמש בקידומת עם פיזור טוב לשמות המשימות, כמו גיבוב של התוכן.
אם אתם מקצים שמות משלכם למשימות, שימו לב שהאורך המקסימלי של השם הוא 500 תווים, והשם יכול להכיל אותיות רישיות וקטנות, מספרים, קווים תחתונים ומקפים.
הוספת משימות באופן אסינכרוני
כברירת מחדל, הקריאות שמוסיפות משימות לתורים הן סינכרוניות. ברוב התרחישים, קריאות סנכרוניות פועלות בצורה תקינה. הוספת משימה לתור היא בדרך כלל פעולה מהירה. יש אחוז קטן של פעולות להוספת משימות שיכולות להימשך הרבה יותר זמן, אבל הזמן החציוני להוספת משימה הוא פחות מ-5 אלפיות השנייה.
אי אפשר לבצע באצ'ינג של פעולות להוספת משימות לתורים שונים, ולכן Task Queue API מספק גם קריאות אסינכרוניות שמאפשרות להוסיף את המשימות האלה במקביל, וכך לצמצם עוד יותר את זמן האחזור. האפשרות הזו שימושית אם אתם מפתחים אפליקציה שרגישה מאוד לזמן אחזור, וצריכה לבצע כמה פעולות של הוספת משימות לכמה תורים שונים בו-זמנית.
אם רוצים לבצע קריאות אסינכרוניות לתור משימות, צריך להשתמש בשיטות האסינכרוניות שמסופקות על ידי המחלקה
הוספת משימות לתור בטרנזקציות של Cloud Datastore
אפשר להוסיף משימה לתור כחלק מטרנזקציית Datastore, כך שהמשימה תתווסף לתור – ומובטח שהיא תתווסף לתור – רק אם הטרנזקציה תאושר בהצלחה. משימות שנוספו ב טרנזקציה נחשבות לחלק ממנה, ויש להן את אותה רמה של טרנזקציה .אפליקציה לא יכולה להוסיף יותר מחמש משימות טרנזקציונליות לתורי משימות במהלך טרנזקציה אחת. למשימות טרנזקציונליות אסור להכיל שמות שצוינו על ידי המשתמש.
בדוגמת הקוד הבאה אפשר לראות איך להוסיף משימות טרנזקציונליות לתור דחיפה (push queue) כחלק מטרנזקציה ב-Datastore:
import (
"net/url"
"golang.org/x/net/context"
"google.golang.org/appengine/v2"
"google.golang.org/appengine/v2/datastore"
"google.golang.org/appengine/v2/taskqueue"
)
func f(ctx context.Context) {
err := datastore.RunInTransaction(ctx, func(ctx context.Context) error {
t := taskqueue.NewPOSTTask("/worker", url.Values{
// ...
})
// Use the transaction's context when invoking taskqueue.Add.
_, err := taskqueue.Add(ctx, t, "")
if err != nil {
// Handle error
}
// ...
return nil
}, nil)
if err != nil {
// Handle error
}
// ...
}
שימוש ב delayed package במקום בשירות worker
הגדרת handler לכל משימה נפרדת (כפי שמתואר בקטעים הקודמים) יכולה להיות מסורבלת, וכך גם סדרות וביטול סדרות של ארגומנטים מורכבים למשימה – במיוחד אם יש לכם הרבה משימות מגוונות אבל קטנות שאתם רוצים להריץ בתור. Go SDK כולל חבילה (appengine/delay) שחושפת API פשוט שמאפשר לעקוף את כל העבודה של הגדרת מטפלים ייעודיים במשימות ושל סדרות וביטול סדרות של הפרמטרים.
כדי להשתמש בחבילה delay:
חבילת delay מבצעת סריאליזציה של בקשה להפעלת פונקציה והארגומנטים שלה, ואז מוסיפה אותה לתור המשימות. כשהמשימה מופעלת, חבילת delay מפעילה את הפונקציה.
מידע נוסף על השימוש בחבילת delay זמין במאמר בנושא delay.
עבודה עם משימות באפליקציה לפי עקרון ה-Multi-tenancy
כברירת מחדל, תורי push משתמשים במרחב השמות הנוכחי כפי שהוגדר במנהל מרחבי השמות בזמן יצירת המשימה. אם האפליקציה משתמשת בגישה מרובת דיירים, כדאי לעיין ב-Namespaces API.