יצירת משימות Push

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

יצירת משימה חדשה

כדי ליצור משימה ולהוסיף אותה לתור, קוראים לפונקציה taskqueue.Add.

import("google.golang.org/appengine/v2/taskqueue")

ציון שירות העובדים

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

target

היעד מציין את השירות שיקבל את בקשת ה-HTTP כדי לבצע את המשימה. זוהי מחרוזת שמציינת שירות/גרסה/מופע באחד מהפורמטים הקנוניים. הטפסים הכי נפוצים הם:

    service
    version.service
    instance.version.service

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

  • מצהירים על היעד כשיוצרים את המשימה. אפשר להגדיר את היעד באופן מפורש כשיוצרים את האובייקט Task על ידי הגדרת הכותרת Host:

    h := http.Header{}
    h.Add("Host", "versionHostname")
    task := taskqueue.Task{
    	Header: h,
    }

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

כדי לבצע קריאות אסינכרוניות לתור משימות, צריך להשתמש בשיטות האסינכרוניות שסופקו על ידי המחלקה Queue של

הוספת משימות לתור בטרנזקציות של 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
    }
    // ...
}

שימוש בחבילת העיכובבמקום בשירות worker

הגדרת handler לכל משימה נפרדת (כפי שמתואר בקטעים הקודמים) יכולה להיות מסורבלת, וכך גם סדרות וביטול סדרות של ארגומנטים מורכבים למשימה – במיוחד אם יש לכם הרבה משימות מגוונות אבל קטנות שאתם רוצים להריץ בתור. ‫Go SDK כולל חבילה (appengine/delay) שחושפת API פשוט שמאפשר לכם לעקוף את כל העבודה של הגדרת רכיבי handler ייעודיים למשימות ושל סדרות וביטול סדרות של הפרמטרים.

כדי להשתמש בחבילה delay:

var expensiveFunc = delay.Func("some-arbitrary-key", func(ctx context.Context, a string, b int) {
	// do something expensive!
})

// Somewhere else
expensiveFunc.Call(ctx, "Hello, world!", 42)

החבילה delay מבצעת סריאליזציה של בקשה להפעלת פונקציה והארגומנטים שלה, ואז מוסיפה אותה לתור המשימות. כשמבצעים את המשימה, חבילת delay מפעילה את הפונקציה.

מידע נוסף על השימוש בחבילת delay זמין במאמר בנושא delay.

עבודה עם משימות באפליקציה לפי עקרון ה-Multi-tenancy

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

המאמרים הבאים