טפל באירועי מחזור החיים של התוסף שלך

התוסף שלך יכול לכלול פונקציות של Cloud Tasks המופעלות כאשר מופע הרחבה עובר כל אחד מאירועי מחזור החיים הבאים:

  • מותקן מופע של התוסף
  • מופע של התוסף מעודכן לגרסה חדשה
  • תצורה של מופע הרחבה השתנתה

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

כמה מקרי שימוש אחרים של טריגרים של אירועי מחזור חיים כוללים:

  • אוטומציה של הגדרה לאחר ההתקנה (יצירת רשומות מסד נתונים, אינדקס וכו')
  • אם אתה צריך לפרסם שינויים שאינם תואמים לאחור, העבר נתונים אוטומטית בעת עדכון

מטפלים באירועי מחזור חיים קצרים

אם המשימה שלך יכולה לפעול במלואה בתוך משך הזמן המקסימלי של פונקציות ענן (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 של התוסף שלך, בצע את הפעולות הבאות:

  1. רשום את הפונקציה שלך כמשאב הרחבה עם ערכת המאפיינים 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: {}
    
  2. רשום את הפונקציה שלך כמטפל עבור אירוע מחזור חיים אחד או יותר:

    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 . כל האירועים הללו הם אופציונליים.

  3. מומלץ : אם משימת העיבוד אינה נדרשת כדי שהתוסף שלך יעבוד, הוסף פרמטר בהגדרת משתמש המאפשר למשתמשים לבחור אם להפעיל אותו.

    לדוגמה, הוסף פרמטר כמו הבא:

    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}.`
);

כדי לדווח על שגיאות שאכן משאירות את התוסף בלתי שמיש, התקשר ל- setFatalError() .

NONE

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

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

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