برنامه افزودنی شما میتواند شامل عملکردهای 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 در اسناد 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
افزونهها همگی از کنترلکنندههای رویداد چرخه حیات برای تکمیل دادهها استفاده میکنند.