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