Lebenszyklus-Ereignisse der Erweiterung verarbeiten

Ihre Erweiterung kann Cloud Tasks Funktionen enthalten die ausgelöst werden, wenn eine Erweiterungsinstanz eine der folgenden Aktionen durchläuft Lebenszyklus-Ereignisse:

  • Eine Instanz der Erweiterung ist installiert
  • Eine Instanz der Erweiterung wird auf eine neue Version aktualisiert
  • Die Konfiguration einer Erweiterungs-Instanz wird geändert

Einer der wichtigsten Anwendungsfälle dieser Funktion ist das Backfill von Daten. Für Angenommen, Sie erstellen eine Erweiterung, die Vorschauen für Miniaturansichten generiert. von Bildern, die in einen Cloud Storage-Bucket hochgeladen wurden. Die Hauptfunktion der Erweiterung in einer Funktion ausgeführt, die durch das Ereignis onFinalize Cloud Storage ausgelöst wird. Es werden jedoch nur Bilder berücksichtigt, die nach der Installation der Erweiterung hochgeladen wurden. verarbeitet werden. Wenn Sie in Ihrer Erweiterung eine Funktion einbinden, die durch das Lebenszyklusereignis onInstall ausgelöst wird, können Sie auch Miniaturansichten von vorhandenen Bildern generieren, wenn die Erweiterung installiert ist.

Weitere Anwendungsfälle für Trigger für Lebenszyklusereignisse:

  • Einrichtung nach der Installation automatisieren (Erstellen von Datenbankeinträgen, Indexierung usw.)
  • Wenn Sie nicht abwärtskompatible Änderungen veröffentlichen müssen, migrieren Sie Daten bei Aktualisierung

Kurzlebige Lebenszyklus-Ereignis-Handler

Wenn Ihre Aufgabe innerhalb des Maximale Dauer für Cloud Functions (9 Minuten mit der API der ersten Generation), können Sie Ihr Lebenszyklusereignis Handler als einzelne Funktion, die beim onDispatch-Ereignis der Aufgabenwarteschlange ausgelöst wird:

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

Führen Sie dann in der Datei extension.yaml Ihrer Erweiterung folgende Schritte aus:

  1. Funktion als Erweiterungsressource mit taskQueueTrigger registrieren festgelegt ist. Wenn Sie für taskQueueTrigger die leere Karte ({}) festlegen, Erweiterung stellt eine Cloud Tasks-Warteschlange mit der Standardeinstellung bereit Einstellungen können Sie optional diese Einstellungen anpassen.

    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. Registrieren Sie Ihre Funktion als Handler für ein oder mehrere Lifecycle-Events:

    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
    
    

    Sie können Funktionen für die folgenden Ereignisse registrieren: onInstall, onUpdate und onConfigure. Alle diese Ereignisse sind optional.

  3. Empfohlen: Wenn die Verarbeitung Ihrer Erweiterung nicht erforderlich ist fügen Sie einen vom Nutzer konfigurierten Parameter mit der Nutzer entscheiden können, ob sie die Funktion aktivieren möchten.

    Fügen Sie beispielsweise einen Parameter wie den folgenden hinzu:

    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
    

    Wenn der Parameter in Ihrer Funktion auf false festgelegt ist, beenden Sie die Funktion vorzeitig:

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

Lang andauernde Aufgaben ausführen

Wenn Ihre Aufgabe nicht innerhalb der maximalen Dauer von Cloud Functions abgeschlossen werden kann, die Aufgabe in Unteraufgaben aufzuteilen und jede Unteraufgabe der Reihe nach auszuführen, indem Sie sie in die Warteschlange stellen. Jobs mit TaskQueue.enqueue() des Admin SDK .

Angenommen, Sie möchten ein Backfill für Cloud Firestore-Daten ausführen. Sie können Die Dokumentsammlung mithilfe von Abfrage-Cursors in Blöcke aufteilen. Fahren Sie nach der Verarbeitung eines Blocks mit dem Startversatz fort und stellen Sie einen weiteren Block in die Warteschlange ein. wie unten dargestellt:

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

Fügen Sie die Funktion zu extension.yaml hinzu, wie in der vorherigen Abschnitt.

Status der Berichterstellung

Wenn alle Verarbeitungsfunktionen abgeschlossen sind, entweder erfolgreich oder mit einem Fehler: Status der Aufgabe über die Erweiterungslaufzeit des Admin SDK melden . Nutzer sehen diesen Status auf der Seite mit den Details zur Erweiterung in der Firebase-Konsole.

Erfolgreicher Abschluss und nicht schwerwiegende Fehler

Um den erfolgreichen Abschluss und nicht schwerwiegende Fehler zu melden (Fehler, bei denen das in einen nicht funktionsfähigen Zustand versetzt wird, verwenden Sie die setProcessingState()-Laufzeitmethode der Erweiterung:

import { getExtensions } from "firebase-admin/extensions";

// ...

getExtensions().runtime().setProcessingState(processingState, message);

Sie können die folgenden Status festlegen:

Nicht schwerwiegende Status
PROCESSING_COMPLETE

Wird verwendet, um den erfolgreichen Abschluss der Aufgabe zu melden. Beispiel:

getExtensions().runtime().setProcessingState(
  "PROCESSING_COMPLETE",
  `Backfill complete. Successfully processed ${numSuccess} documents.`
);
PROCESSING_WARNING

Verwenden Sie diese Option, wenn der Vorgang teilweise erfolgreich war. Beispiel:

getExtensions().runtime().setProcessingState(
  "PROCESSING_WARNING",
  `Backfill complete. ${numSuccess} documents processed successfully.`
    + ` ${numFailed} documents failed to process. ${listOfErrors}.`
    + ` ${instructionsToFixTheProblem}`
);
PROCESSING_FAILED

Wird zum Melden von Fehlern verwendet, die einen Abschluss der Aufgabe verhindern, aber nicht die Erweiterung unbrauchbar. Beispiel:

getExtensions().runtime().setProcessingState(
  "PROCESSING_FAILED",
  `Backfill failed. ${errorMsg} ${optionalInstructionsToFixTheProblem}.`
);

Wenn die Erweiterung durch einen Fehler nicht mehr verwendet werden kann, rufen Sie setFatalError() auf.

NONE

Zum Löschen des Aufgabenstatus. Sie können diese Option verwenden, um der Statusmeldung von der Konsole aus (z. B. nach einer gewissen Zeit Zeit verstrichen ist, seitdem PROCESSING_COMPLETE festgelegt wurde. Beispiel:

getExtensions().runtime().setProcessingState("NONE");

Schwerwiegende Fehler

Wenn ein Fehler auftritt, der verhindert, dass die Erweiterung funktioniert – Beispiel: Wenn eine erforderliche Einrichtungsaufgabe fehlschlägt, melden Sie den schwerwiegenden Fehler setFatalError():

import { getExtensions } from "firebase-admin/extensions";

// ...

getExtensions().runtime().setFatalError(`Post-installation setup failed. ${errorMessage}`);

Aufgabenwarteschlange abstimmen

Wenn Sie die Eigenschaft taskQueueTrigger auf {} setzen, wird die Erweiterung Cloud Tasks-Warteschlange mit den Standardeinstellungen bereitstellen, wenn eine Erweiterung Instanz installiert ist. Alternativ können Sie die Gleichzeitigkeit der Aufgabenwarteschlange optimieren Einschränkungen und das Wiederholungsverhalten durch Angabe bestimmter Werte:

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

Siehe Cloud Tasks-Warteschlangen konfigurieren in der Google Cloud-Dokumentation finden Sie Details zu diesen Parametern.

Versuchen Sie nicht, Parameter für Aufgabenwarteschlangen durch Übergabe an taskQueue() anzugeben. Diese Einstellungen werden zugunsten der Konfiguration in extension.yaml ignoriert und die Standardeinstellungen der Konfiguration.

Dies funktioniert beispielsweise nicht:

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(
    // ...
  );

Die Eigenschaft taskQueueTrigger in extension.yaml ist die einzige Möglichkeit, die Aufgabenwarteschlangen einer Erweiterung zu konfigurieren.

Beispiele

Die offizielle storage-resize-images, firestore-bigquery-export, und firestore-translate-text Erweiterungen verwenden alle Lifecycle-Event-Handler, um Daten im Backfill aufzufüllen.