Xử lý các sự kiện trong vòng đời của tiện ích

Tiện ích của bạn có thể bao gồm Cloud Tasks hàm kích hoạt khi một bản sao tiện ích trải qua bất kỳ sự kiện nào sau đây các sự kiện trong vòng đời:

  • Một bản sao của tiện ích đã được cài đặt
  • Một bản sao của tiện ích đã được cập nhật lên phiên bản mới
  • Đã thay đổi cấu hình của một bản sao tiện ích

Một trong những trường hợp sử dụng quan trọng nhất của tính năng này là điền lại dữ liệu. Để ví dụ: giả sử bạn đang tạo một tiện ích tạo bản xem trước hình thu nhỏ hình ảnh được tải lên bộ chứa Cloud Storage. Chức năng chính của tiện ích sẽ được thực hiện trong một hàm được kích hoạt bởi sự kiện onFinalize Cloud Storage. Tuy nhiên, chỉ những hình ảnh được tải lên sau khi cài đặt tiện ích mới được đã xử lý. Bằng cách đưa vào tiện ích của bạn một hàm được kích hoạt bởi onInstall sự kiện trong vòng đời, bạn cũng có thể tạo bản xem trước hình thu nhỏ của bất kỳ các hình ảnh hiện có khi cài đặt tiện ích.

Sau đây là một số trường hợp sử dụng khác của trình kích hoạt sự kiện trong vòng đời:

  • Tự động hoá quy trình thiết lập sau khi cài đặt (tạo bản ghi cơ sở dữ liệu, lập chỉ mục, v.v.)
  • Nếu bạn phải xuất bản các thay đổi không tương thích ngược, hãy tự động di chuyển dữ liệu khi cập nhật

Trình xử lý sự kiện chạy trong thời gian ngắn trong vòng đời

Nếu tác vụ của bạn có thể chạy hoàn toàn trong thời lượng tối đa Cloud Functions (9 phút sử dụng API thế hệ đầu tiên), bạn có thể viết sự kiện trong vòng đời của mình trình xử lý dưới dạng một hàm duy nhất kích hoạt trên sự kiện onDispatch hàng đợi tác vụ:

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

Sau đó, trong tệp extension.yaml của tiện ích, hãy làm như sau:

  1. Đăng ký hàm của bạn dưới dạng tài nguyên tiện ích bằng taskQueueTrigger tập hợp thuộc tính. Nếu bạn đặt taskQueueTrigger thành bản đồ trống ({}), tiện ích này sẽ cung cấp hàng đợi Cloud Tasks bằng cách sử dụng cài đặt; bạn có thể điều chỉnh các chế độ cài đặt này (không bắt buộc).

    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. Đăng ký hàm của bạn với vai trò là trình xử lý cho một hoặc nhiều sự kiện trong vòng đời:

    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
    
    

    Bạn có thể đăng ký hàm cho bất kỳ sự kiện nào sau đây: onInstall, onUpdateonConfigure. Tất cả những sự kiện này là không bắt buộc.

  3. Đề xuất: Nếu tiện ích của bạn không bắt buộc phải thực hiện nhiệm vụ xử lý để làm việc, hãy thêm một thông số do người dùng định cấu hình để người dùng chọn có bật tính năng đó hay không.

    Ví dụ: thêm một thông số như sau:

    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
    

    Và trong hàm của bạn, nếu tham số được đặt thành false, hãy thoát sớm:

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

Thực hiện các tác vụ chạy trong thời gian dài

Nếu việc cần làm của bạn không thể hoàn thành trong khoảng thời gian tối đa là Cloud Functions, chia công việc thành các việc phụ cần làm và thực hiện từng việc phụ theo trình tự bằng cách thêm vào hàng đợi công việc bằng TaskQueue.enqueue() của SDK dành cho quản trị viên .

Ví dụ: giả sử bạn muốn chèn lấp dữ liệu Cloud Firestore. Bạn có thể chia bộ sưu tập tài liệu thành nhiều phần bằng cách sử dụng con trỏ truy vấn. Sau khi xử lý một đoạn, hãy chuyển độ lệch ban đầu rồi thêm một đoạn khác vào hàng đợi lệnh gọi hàm như minh hoạ dưới đây:

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

Thêm hàm vào extension.yaml như được mô tả trong phần trước.

Trạng thái báo cáo

Khi tất cả các chức năng xử lý của bạn đã kết thúc, có thể là thành công hoặc lỗi, hãy báo cáo trạng thái của tác vụ bằng cách sử dụng thời gian chạy tiện ích của SDK dành cho quản trị viên . Người dùng có thể thấy trạng thái này trên trang chi tiết về tiện ích trong Bảng điều khiển Firebase.

Hoàn tất thành công và các lỗi không nghiêm trọng

Để báo cáo việc hoàn tất thành công và các lỗi không nghiêm trọng (các lỗi không đặt tiện ích sang trạng thái không hoạt động), hãy sử dụng phiên bản SDK dành cho quản trị viên Phương thức thời gian chạy của tiện ích setProcessingState():

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

// ...

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

Bạn có thể đặt các trạng thái sau:

Tiểu bang không nghiêm trọng
PROCESSING_COMPLETE

Dùng để báo cáo việc hoàn thành việc cần làm. Ví dụ:

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

Sử dụng để báo cáo thành công một phần. Ví dụ:

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

Dùng để báo cáo những lỗi khiến tác vụ không hoàn thành được nhưng không thực hiện không sử dụng được tiện ích đó. Ví dụ:

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

Để báo cáo lỗi khiến không sử dụng được tiện ích, hãy gọi setFatalError().

NONE

Dùng để xoá trạng thái của việc cần làm. Bạn có thể tuỳ ý sử dụng tuỳ chọn này để xoá thông báo trạng thái từ bảng điều khiển (ví dụ: sau khi đã trôi qua kể từ khi thiết lập PROCESSING_COMPLETE). Ví dụ:

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

Lỗi nghiêm trọng

Nếu xảy ra lỗi khiến tiện ích không hoạt động được—cho ví dụ: tác vụ thiết lập bắt buộc không thành công—báo cáo lỗi nghiêm trọng với setFatalError():

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

// ...

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

Điều chỉnh hàng đợi tác vụ

Nếu bạn đặt thuộc tính taskQueueTrigger thành {}, tiện ích của bạn sẽ cung cấp hàng đợi Cloud Tasks với chế độ cài đặt mặc định khi tiện ích thực thể đã được cài đặt. Hoặc bạn có thể điều chỉnh tính đồng thời của hàng đợi tác vụ giới hạn và thử lại hành vi bằng cách cung cấp các giá trị cụ thể:

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

Xem bài viết Định cấu hình hàng đợi của Cloud Tasks trong tài liệu của Google Cloud để biết thông tin chi tiết về các thông số này.

Đừng chỉ định các tham số của hàng đợi tác vụ bằng cách truyền các tham số đó tới taskQueue(). Các chế độ cài đặt này bị bỏ qua và thay vào đó, cấu hình trong extension.yaml và các cấu hình mặc định.

Ví dụ: tính năng này sẽ không hoạt động:

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

Thuộc tính taskQueueTrigger trong extension.yaml là cách duy nhất để định cấu hình hàng đợi tác vụ của tiện ích.

Ví dụ

storage-resize-images chính thức, firestore-bigquery-export, và firestore-translate-text tất cả tiện ích đều sử dụng trình xử lý sự kiện trong vòng đời để bổ sung dữ liệu.