處理擴充功能的生命週期事件(')

您的擴充功能可包含 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 檔案中執行下列操作:

  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
    
    

    你可以註冊下列事件的函式:onInstallonUpdateonConfigure。這些事件全都是選擇性事件。

  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 的期限內,無法完成工作, 把工作分成子工作,然後依序執行各項子工作 使用 Admin SDK 的 TaskQueue.enqueue() 建立工作 方法。

舉例來說,假設您要補充 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 控制台。

成功完成與一般錯誤

為了回報成功完成及不嚴重的錯誤 (未將 停止運作後,請使用 Admin SDK 的 setProcessingState() 擴充功能執行階段方法:

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

請參閱設定 Cloud Tasks 佇列。 ,進一步瞭解這些參數。

請勿嘗試將工作佇列參數傳遞至 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(
    // ...
  );

extension.yaml 中的 taskQueueTrigger 屬性是設定的唯一方法 擴充功能的工作佇列。

範例

官方版 storage-resize-imagesfirestore-bigquery-export, 和firestore-translate-text 所有擴充功能都會使用生命週期事件處理常式來補充資料。