התוסף יכול לכלול פונקציות Cloud Tasks שמופעלות כשמכונה של תוסף עוברת את אחד מאירועי מחזור החיים הבאים:
- מותקן מופע של התוסף
- מופע של התוסף מעודכן לגרסה חדשה
- הגדרות של מכונה של תוסף השתנו
אחד מהתרחישים החשובים ביותר לשימוש בתכונה הזו הוא מילוי נתונים. לדוגמה, נניח שאתם מפתחים תוסף שיוצר תמונות ממוזערות של תמונות שהועלו לקטגוריה Cloud Storage. העבודה העיקרית של התוסף תתבצע בפונקציה שתופעל על ידי האירוע onFinalize
Cloud Storage.
עם זאת, רק תמונות שהועלו אחרי התקנת התוסף יעברו עיבוד. אם תכללו בתוסף פונקציה שתופעל על ידי אירוע מחזור החיים onInstall
, תוכלו גם ליצור תצוגות מקדימות של תמונות קיימות כשהתוסף מותקן.
דוגמאות נוספות לתרחישים לדוגמה של טריגרים של אירועים במחזור החיים:
- אוטומציה של ההגדרה לאחר ההתקנה (יצירת רשומות במסד נתונים, הוספה לאינדקס וכו')
- אם אתם צריכים לפרסם שינויים שלא תואמים לגרסאות קודמות, כדאי להעביר את הנתונים באופן אוטומטי במהלך העדכון
גורמים שמטפלים באירועים במחזור חיים לטווח קצר
אם המשימה יכולה לפעול במלואה במשך הזמן המרבי Cloud Functions (9 דקות באמצעות ה-API מדור ראשון), אפשר לכתוב את הטיפול באירועי מחזור החיים כפונקציה אחת שמופעל באירוע onDispatch
של תור המשימות:
export const myTaskFunction = functions.tasks.taskQueue()
.onDispatch(async () => {
// Complete your lifecycle event handling task.
// ...
// When processing is complete, report status to the user (see below).
});
לאחר מכן, בקובץ extension.yaml
של התוסף, מבצעים את הפעולות הבאות:
רושמים את הפונקציה כמשאב תוסף באמצעות קבוצת הנכסים
taskQueueTrigger
. אם מגדירים אתtaskQueueTrigger
למפה הריקה ({}
), התוסף יקצה תור Cloud Tasks באמצעות הגדרות ברירת המחדל. אפשר גם לשנות את ההגדרות האלה.resources: - name: myTaskFunction type: firebaseextensions.v1beta.function description: >- Describe the task performed when the function is triggered by a lifecycle event properties: location: ${LOCATION} taskQueueTrigger: {}
רושמים את הפונקציה כמתנהלת לאירוע אחד או יותר במחזור החיים:
resources: - ... lifecycleEvents: onInstall: function: myTaskFunction processingMessage: Resizing your existing images onUpdate: function: myOtherTaskFunction processingMessage: Setting up your extension onConfigure: function: myOtherTaskFunction processingMessage: Setting up your extension
אפשר לרשום פונקציות לכל אחד מהאירועים הבאים:
onInstall
,onUpdate
ו-onConfigure
. כל האירועים האלה הם אופציונליים.מומלץ: אם משימה העיבוד לא נדרשת כדי שהתוסף יפעל, מוסיפים פרמטר שמוגדר על ידי המשתמש שמאפשר למשתמשים לבחור אם להפעיל אותו.
לדוגמה, מוסיפים פרמטר כמו זה:
params: - param: DO_BACKFILL label: Backfill existing images description: > Should existing, unresized images in the Storage bucket be resized as well? type: select options: - label: Yes value: true - label: No value: false
ובפונקציה, אם הפרמטר מוגדר כ-
false
, יוצאים מוקדם:export const myTaskFunction = functions.tasks.taskQueue() .onDispatch(async () => { if (!process.env.DO_BACKFILL) { await runtime.setProcessingState( "PROCESSING_COMPLETE", "Existing images were not resized." ); return; } // Complete your lifecycle event handling task. // ... });
ביצוע משימות ממושכות
אם המשימה לא יכולה להסתיים במהלך משך הזמן המרבי Cloud Functions, צריך לפצל אותה לתתי-משימות ולבצע כל תת-משימה ברצף על ידי הוספת משימות לתור באמצעות השיטה TaskQueue.enqueue()
של Admin SDK.
לדוגמה, נניח שרוצים למלא חוסרים בנתונים של Cloud Firestore. אפשר לפצל את אוסף המסמכים למקטעים באמצעות סמן שאילתות. אחרי עיבוד מקטע, מעבירים את הזזת ההתחלה ומוסיפים לתור קריאה נוספת לפונקציה, כפי שמתואר בהמשך:
import { getFirestore } from "firebase-admin/firestore";
import { getFunctions } from "firebase-admin/functions";
exports.backfilldata = functions.tasks.taskQueue().onDispatch(async (data) => {
// When a lifecycle event triggers this function, it doesn't pass any data,
// so an undefined offset indicates we're on our first invocation and should
// start at offset 0. On subsequent invocations, we'll pass an explicit
// offset.
const offset = data["offset"] ?? 0;
// Get a batch of documents, beginning at the offset.
const snapshot = await getFirestore()
.collection(process.env.COLLECTION_PATH)
.startAt(offset)
.limit(DOCS_PER_BACKFILL)
.get();
// Process each document in the batch.
const processed = await Promise.allSettled(
snapshot.docs.map(async (documentSnapshot) => {
// Perform the processing.
})
);
// If we processed a full batch, there are probably more documents to
// process, so enqueue another invocation of this function, specifying
// the offset to start with.
//
// If we processed less than a full batch, we're done.
if (processed.length == DOCS_PER_BACKFILL) {
const queue = getFunctions().taskQueue(
"backfilldata",
process.env.EXT_INSTANCE_ID
);
await queue.enqueue({
offset: offset + DOCS_PER_BACKFILL,
});
} else {
// Processing is complete. Report status to the user (see below).
}
});
מוסיפים את הפונקציה ל-extension.yaml
כפי שמתואר בחלק הקודם.
סטטוס הדיווח
כשכל פונקציות העיבוד מסתיימות, בין שבאופן תקין ובין שבאופן שמוצגת בו שגיאה, מדווחים על סטטוס המשימה באמצעות השיטות של סביבת זמן הריצה של התוסף ב-Admin SDK. המשתמשים יכולים לראות את הסטטוס הזה בדף הפרטים של התוסף במסוף Firebase.
השלמה מוצלחת ושגיאות לא קטלניות
כדי לדווח על השלמה מוצלחת ועל שגיאות לא קטלניות (שגיאות שלא מעבירות את התוסף למצב לא פונקציונלי), משתמשים בשיטת זמן הריצה של התוסף setProcessingState()
ב-Admin SDK:
import { getExtensions } from "firebase-admin/extensions";
// ...
getExtensions().runtime().setProcessingState(processingState, message);
אפשר להגדיר את המצבים הבאים:
מצבים לא קטלניים | |
---|---|
PROCESSING_COMPLETE |
משתמשים בה כדי לדווח על השלמת משימה. דוגמה: getExtensions().runtime().setProcessingState( "PROCESSING_COMPLETE", `Backfill complete. Successfully processed ${numSuccess} documents.` ); |
PROCESSING_WARNING |
משתמשים בקוד הזה כדי לדווח על הצלחה חלקית. דוגמה: getExtensions().runtime().setProcessingState( "PROCESSING_WARNING", `Backfill complete. ${numSuccess} documents processed successfully.` + ` ${numFailed} documents failed to process. ${listOfErrors}.` + ` ${instructionsToFixTheProblem}` ); |
PROCESSING_FAILED |
משתמשים בה כדי לדווח על שגיאות שמונעות את השלמת המשימה, אבל לא משביתות את התוסף. דוגמה: getExtensions().runtime().setProcessingState( "PROCESSING_FAILED", `Backfill failed. ${errorMsg} ${optionalInstructionsToFixTheProblem}.` ); כדי לדווח על שגיאות שכן מונעות שימוש בתוסף, צריך להתקשר למספר |
NONE |
משתמשים בה כדי למחוק את הסטטוס של המשימה. אפשר להשתמש באפשרות הזו כדי למחוק את הודעת הסטטוס מהמסוף (לדוגמה, אחרי שחולף זמן מה מהגדרת getExtensions().runtime().setProcessingState("NONE"); |
שגיאות קריטיות
אם מתרחשת שגיאה שמונעת מהתוסף לפעול – לדוגמה, משימה חיונית בהגדרה נכשלת – צריך לדווח על השגיאה הקטלנית באמצעות setFatalError()
:
import { getExtensions } from "firebase-admin/extensions";
// ...
getExtensions().runtime().setFatalError(`Post-installation setup failed. ${errorMessage}`);
שינוי ההגדרות של תור המשימות
אם תגדירו את הערך של המאפיין taskQueueTrigger
ל-{}
, התוסף יקצה תור ב-Cloud Tasks עם הגדרות ברירת המחדל כשמכונה של התוסף תותקן. לחלופין, אפשר לשנות את מגבלות התכנות בו-זמנית ואת התנהגות הניסיון החוזר של תור המשימות על ידי מתן ערכים ספציפיים:
resources:
- name: myTaskFunction
type: firebaseextensions.v1beta.function
description: >-
Perform a task when triggered by a lifecycle event
properties:
location: ${LOCATION}
taskQueueTrigger:
rateLimits:
maxConcurrentDispatches: 1000
maxDispatchesPerSecond: 500
retryConfig:
maxAttempts: 100 # Warning: setting this too low can prevent the function from running
minBackoffSeconds: 0.1
maxBackoffSeconds: 3600
maxDoublings: 16
lifecycleEvents:
onInstall:
function: myTaskFunction
processingMessage: Resizing your existing images
onUpdate:
function: myTaskFunction
processingMessage: Setting up your extension
onConfigure:
function: myOtherTaskFunction
processingMessage: Setting up your extension
פרטים על הפרמטרים האלה מופיעים במאמר הגדרת תורים ב-Cloud Tasks במסמכי העזרה של Google Cloud.
אין לנסות לציין פרמטרים של תור המשימות על ידי העברה שלהם אל taskQueue()
.
המערכת מתעלמת מההגדרות האלה ומשתמשת בתצורה שמופיעה ב-extension.yaml
ובברירות המחדל של התצורה.
לדוגמה, האפשרות הבאה לא תפעל:
export const myBrokenTaskFunction = functions.tasks
// DON'T DO THIS IN AN EXTENSION! THESE SETTINGS ARE IGNORED.
.taskQueue({
retryConfig: {
maxAttempts: 5,
minBackoffSeconds: 60,
},
rateLimits: {
maxConcurrentDispatches: 1000,
maxDispatchesPerSecond: 10,
},
})
.onDispatch(
// ...
);
המאפיין taskQueueTrigger
בקובץ extension.yaml
הוא הדרך היחידה להגדיר את תורי המשימות של התוסף.
דוגמאות
התוספים הרשמיים storage-resize-images
, firestore-bigquery-export
ו-firestore-translate-text
משתמשים בטיפול באירועים במחזור החיים כדי למלא את הנתונים.