了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

अपने एक्सटेंशन के जीवनचक्र ईवेंट प्रबंधित करें

आपके एक्सटेंशन में क्लाउड टास्क फ़ंक्शन शामिल हो सकते हैं, जो तब ट्रिगर होते हैं, जब कोई एक्सटेंशन इंस्टेंस निम्न जीवनचक्र ईवेंट से गुज़रता है:

  • एक्सटेंशन का एक उदाहरण स्थापित है
  • एक्सटेंशन का एक उदाहरण एक नए संस्करण में अपडेट किया गया है
  • एक एक्सटेंशन इंस्टेंस का कॉन्फ़िगरेशन बदल दिया गया है

इस सुविधा के सबसे महत्वपूर्ण उपयोग मामलों में से एक डेटा बैकफ़िलिंग है। उदाहरण के लिए, मान लें कि आप एक ऐसा एक्सटेंशन बना रहे हैं, जो क्लाउड स्टोरेज बकेट में अपलोड की गई इमेज का थंबनेल प्रीव्यू जनरेट करता है। आपके एक्सटेंशन का मुख्य कार्य onFinalize Cloud Storage ईवेंट द्वारा ट्रिगर किए गए फ़ंक्शन में किया जाएगा। हालांकि, एक्सटेंशन इंस्टॉल होने के बाद अपलोड की गई छवियों को ही संसाधित किया जाएगा। अपने एक्सटेंशन में onInstall जीवनचक्र ईवेंट द्वारा ट्रिगर किए गए फ़ंक्शन को शामिल करके, आप एक्सटेंशन इंस्टॉल होने पर किसी भी मौजूदा छवि के थंबनेल पूर्वावलोकन भी उत्पन्न कर सकते हैं।

जीवनचक्र ईवेंट ट्रिगर्स के कुछ अन्य उपयोग मामलों में शामिल हैं:

  • पोस्ट-इंस्टॉल सेटअप को स्वचालित करें (डेटाबेस रिकॉर्ड बनाना, अनुक्रमण करना, आदि)
  • यदि आपको पिछड़े-असंगत परिवर्तनों को प्रकाशित करना है, तो अद्यतन होने पर स्वचालित रूप से डेटा माइग्रेट करें

शॉर्ट-रनिंग लाइफसाइकिल इवेंट हैंडलर

यदि आपका कार्य अधिकतम क्लाउड फ़ंक्शंस अवधि (पहली पीढ़ी के एपीआई का उपयोग करके 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 फ़ाइल में, निम्न कार्य करें:

  1. अपने कार्य को taskQueueTrigger संपत्ति सेट के साथ एक विस्तार संसाधन के रूप में पंजीकृत करें। यदि आप taskQueueTrigger खाली मानचित्र ( {} ) पर सेट करते हैं, तो आपका एक्सटेंशन डिफ़ॉल्ट सेटिंग्स का उपयोग करके क्लाउड कार्य कतार का प्रावधान करेगा; आप वैकल्पिक रूप से इन सेटिंग्स को ट्यून कर सकते हैं।

    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. एक या अधिक जीवनचक्र घटनाओं के लिए अपने कार्य को एक हैंडलर के रूप में पंजीकृत करें:

    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 । ये सभी घटनाएँ वैकल्पिक हैं।

  3. अनुशंसित : यदि आपके एक्सटेंशन के कार्य करने के लिए संसाधन कार्य की आवश्यकता नहीं है, तो एक उपयोगकर्ता-कॉन्फ़िगर पैरामीटर जोड़ें जो उपयोगकर्ताओं को यह चुनने देता है कि इसे सक्षम करना है या नहीं।

    उदाहरण के लिए, निम्न जैसा पैरामीटर जोड़ें:

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

दीर्घकालीन कार्यों का निष्पादन

यदि आपका कार्य अधिकतम क्लाउड फ़ंक्शंस अवधि के भीतर पूरा नहीं हो सकता है, तो कार्य को उप-कार्यों में विभाजित करें और प्रत्येक उप-कार्य को व्यवस्थापक SDK के TaskQueue.enqueue() विधि के साथ कार्यों को कतारबद्ध करके निष्पादित करें।

उदाहरण के लिए, मान लें कि आप 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 में जोड़ें, जैसा कि पिछले अनुभाग में बताया गया है।

रिपोर्टिंग स्थिति

जब आपके सभी संसाधन कार्य सफलतापूर्वक या किसी त्रुटि के साथ समाप्त हो जाएं, तो व्यवस्थापक SDK के एक्सटेंशन रनटाइम विधियों का उपयोग करके कार्य की स्थिति की रिपोर्ट करें. उपयोगकर्ता इस स्थिति को Firebase कंसोल में एक्सटेंशन विवरण पृष्ठ पर देख सकते हैं।

सफल समापन और गैर-घातक त्रुटियां

सफल समापन और गैर-घातक त्रुटियों की रिपोर्ट करने के लिए (त्रुटियां जो एक्सटेंशन को गैर-कार्यात्मक स्थिति में नहीं डालती हैं), व्यवस्थापक SDK की setProcessingState() एक्सटेंशन रनटाइम विधि का उपयोग करें:

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

एक्सटेंशन को अनुपयोगी छोड़ने वाली त्रुटियों की रिपोर्ट करने के लिए, setFatalError() पर कॉल करें।

NONE

कार्य की स्थिति साफ़ करने के लिए उपयोग करें। आप कंसोल से स्थिति संदेश को साफ़ करने के लिए वैकल्पिक रूप से इसका उपयोग कर सकते हैं (उदाहरण के लिए, PROCESSING_COMPLETE सेट करने के बाद कुछ समय बीत जाने के बाद)। उदाहरण:

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

घातक त्रुटियाँ

यदि कोई त्रुटि उत्पन्न होती है जो एक्सटेंशन को कार्य करने से रोकती है- उदाहरण के लिए, एक आवश्यक सेटअप कार्य विफल हो रहा है- तो घातक त्रुटि की रिपोर्ट setFatalError() के साथ करें:

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

// ...

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

कार्य कतार ट्यूनिंग

अगर आप taskQueueTrigger प्रॉपर्टी को {} पर सेट करते हैं, तो एक्सटेंशन इंस्टेंस इंस्टॉल होने पर आपका एक्सटेंशन डिफ़ॉल्ट सेटिंग्स के साथ क्लाउड टास्क कतार का प्रावधान करेगा। वैकल्पिक रूप से, आप कार्य कतार की समवर्ती सीमा को ट्यून कर सकते हैं और विशिष्ट मान प्रदान करके व्यवहार को पुनः प्रयास कर सकते हैं:

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

इन पैरामीटरों के विवरण के लिए Google क्लाउड दस्तावेज़ों में क्लाउड कार्य क्यू कॉन्फ़िगर करें देखें।

उदाहरण

आधिकारिक storage-resize-images , firestore-bigquery-export , और firestore-translate-text एक्सटेंशन सभी डेटा को बैकफ़िल करने के लिए जीवनचक्र ईवेंट हैंडलर का उपयोग करते हैं।