يمكن أن تتضمّن إضافتك وظائف Cloud Tasks يتم تشغيلها عندما يمر مثيل الإضافة بأي من أحداث دورة الحياة التالية:
- تم تثبيت نسخة من الإضافة
- يتم تحديث نسخة من الإضافة إلى إصدار جديد
- تم تغيير إعدادات مثيل إضافة
من أهم حالات استخدام هذه الميزة إعادة ملء البيانات. على سبيل المثال، لنفترض أنّك بصدد إنشاء إضافة تنشئ معاينات مصغّرة للصور التي يتم تحميلها إلى حزمة Cloud Storage. سيتم تنفيذ العمل الرئيسي للإضافة في دالة يتم تشغيلها بواسطة الحدث onFinalize
Cloud Storage.
ومع ذلك، سيتم معالجة الصور التي تم تحميلها بعد تثبيت الإضافة فقط. من خلال تضمين دالة يتم تشغيلها بواسطة حدث دورة الحياة onInstall
في الإضافة، يمكنك أيضًا إنشاء معاينات للصور المصغّرة لأي صور حالية عند تثبيت الإضافة.
تشمل بعض حالات الاستخدام الأخرى لمشغّلات أحداث مراحل النشاط ما يلي:
- أتمتة عملية الإعداد بعد التثبيت (إنشاء سجلات قاعدة البيانات والفهرسة وما إلى ذلك)
- إذا كان عليك نشر تغييرات غير متوافقة مع الإصدارات السابقة، عليك نقل البيانات تلقائيًا عند التحديث
معالِجات أحداث مراحل النشاط القصيرة المدة
إذا كان بإمكان مهمتك أن تعمل بشكل كامل ضمن الحد الأقصى Cloud Functions للمدة (9 دقائق باستخدام الجيل الأول من واجهة برمجة التطبيقات)، يمكنك كتابة معالج حدث دورة الحياة كدالة واحدة يتم تشغيلها عند حدث 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()
في حزمة 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 Tasks في مستندات 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
معالجات أحداث مراحل النشاط لتعبئة البيانات السابقة.