Cloud Tasks की मदद से, फ़ंक्शन को सूची में जोड़ें

टास्क क्यू फ़ंक्शन, Google Cloud Tasks का फ़ायदा उठाते हैं. इससे आपके ऐप्लिकेशन को ऐसे टास्क एसिंक्रोनस तरीके से चलाने में मदद मिलती है जिनमें ज़्यादा समय लगता है, ज़्यादा संसाधनों की ज़रूरत होती है या बैंडविथ की सीमा होती है. ये टास्क, आपके ऐप्लिकेशन के मुख्य फ़्लो से बाहर चलाए जाते हैं.

उदाहरण के लिए, मान लें कि आपको इमेज फ़ाइलों के बड़े सेट का बैकअप बनाना है. ये फ़ाइलें, फ़िलहाल रेट लिमिट वाले एपीआई पर होस्ट की गई हैं. उस एपीआई का ज़िम्मेदारी से इस्तेमाल करने के लिए, आपको उसकी रेट लिमिट का पालन करना होगा. इसके अलावा, इस तरह के लंबे समय तक चलने वाले जॉब में, टाइम आउट और मेमोरी की सीमाओं की वजह से गड़बड़ी हो सकती है.

इस समस्या को कम करने के लिए, टास्क क्यू फ़ंक्शन लिखा जा सकता है. इसमें टास्क के बुनियादी विकल्प सेट किए जा सकते हैं. जैसे, scheduleTime और dispatchDeadline. इसके बाद, फ़ंक्शन को Cloud Tasks में मौजूद किसी क्यू में भेजा जा सकता है. The Cloud Tasks एनवायरमेंट को खास तौर पर इस तरह डिज़ाइन किया गया है कि इस तरह की कार्रवाइयों के लिए, कंजेशन कंट्रोल और फिर से कोशिश करने की नीतियों को असरदार तरीके से लागू किया जा सके.

टास्क क्यू फ़ंक्शन के साथ काम करने के लिए, Firebase SDK for Cloud Functions for Firebase का वर्शन 3.20.1 और इसके बाद के वर्शन, Firebase Admin SDK के वर्शन 10.2.0 और इसके बाद के वर्शन के साथ इंटरऑपरेट करते हैं.

Firebase के साथ टास्क क्यू फ़ंक्शन का इस्तेमाल करने पर, Cloud Tasks प्रोसेसिंग के लिए शुल्क लग सकता है. ज़्यादा जानकारी के लिए, Cloud Tasksकी कीमत देखें.

टास्क क्यू फ़ंक्शन बनाना

टास्क क्यू फ़ंक्शन का इस्तेमाल करने के लिए, यह तरीका अपनाएं:

  1. Firebase SDK का इस्तेमाल करके, Cloud Functions के लिए टास्क क्यू फ़ंक्शन लिखें.
  2. एचटीटीपी अनुरोध भेजकर, अपने फ़ंक्शन को ट्रिगर करें और उसकी जांच करें.
  3. Firebase CLI का इस्तेमाल करके, अपने फ़ंक्शन को डिप्लॉय करें. टास्क क्यू फ़ंक्शन को पहली बार डिप्लॉय करने पर, CLI, Cloud Tasks में एक टास्क क्यू बनाएगा. इसमें आपके सोर्स कोड में बताई गई रेट लिमिट और फिर से कोशिश करने के विकल्प शामिल होंगे.
  4. नए टास्क क्यू में टास्क जोड़ें. अगर ज़रूरत हो, तो एक्ज़ीक्यूशन शेड्यूल सेट अप करने के लिए पैरामीटर पास करें. इसके लिए, कोड लिखें का इस्तेमाल करके Admin SDK और उसे Cloud Functions for Firebase पर डिप्लॉय करें.

टास्क क्यू फ़ंक्शन लिखना

इस सेक्शन में दिए गए कोड के सैंपल, ऐसे ऐप्लिकेशन पर आधारित हैं जो एक ऐसी सेवा सेट अप करता है जिससे नासा की 'ऐस्ट्रोनॉमी पिक्चर ऑफ़ द डे' की सभी इमेज का बैकअप लिया जा सकता है. शुरू करने के लिए, ज़रूरी मॉड्यूल इंपोर्ट करें:

Node.js

// Dependencies for task queue functions.
const {onTaskDispatched} = require("firebase-functions/tasks");
const {onRequest, HttpsError} = require("firebase-functions/https");
const {getFunctions} = require("firebase-admin/functions");
const {logger} = require("firebase-functions");

// Dependencies for image backup.
const path = require("path");
const {initializeApp} = require("firebase-admin/app");
const {getStorage} = require("firebase-admin/storage");
const {GoogleAuth} = require("google-auth-library");

Python

# Dependencies for task queue functions.
from google.cloud import tasks_v2
import requests
from firebase_functions.options import RetryConfig, RateLimits, SupportedRegion

# Dependencies for image backup.
from datetime import datetime, timedelta
import json
import pathlib
from urllib.parse import urlparse
from firebase_admin import initialize_app, storage, functions
from firebase_functions import https_fn, tasks_fn, params
import google.auth
from google.auth.transport.requests import AuthorizedSession

टास्क क्यू फ़ंक्शन के लिए, onTaskDispatched या on_task_dispatched का इस्तेमाल करें. टास्क क्यू फ़ंक्शन लिखते समय, हर क्यू के लिए फिर से कोशिश करने और रेट लिमिट से जुड़ा कॉन्फ़िगरेशन सेट किया जा सकता है.

टास्क क्यू फ़ंक्शन कॉन्फ़िगर करना

टास्क क्यू फ़ंक्शन में, कॉन्फ़िगरेशन सेटिंग का एक पावरफ़ुल सेट होता है. इससे, टास्क क्यू की रेट लिमिट और फिर से कोशिश करने के व्यवहार को सटीक तरीके से कंट्रोल किया जा सकता है:

Node.js

exports.backupapod = onTaskDispatched(
    {
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }, async (req) => {

Python

@tasks_fn.on_task_dispatched(
    retry_config=RetryConfig(max_attempts=5, min_backoff_seconds=60),
    rate_limits=RateLimits(max_concurrent_dispatches=10),
)
def backupapod(req: tasks_fn.CallableRequest) -> str:
    """Grabs Astronomy Photo of the Day (APOD) using NASA's API."""
  • retryConfig.maxAttempts=5: टास्क क्यू में मौजूद हर टास्क के लिए, पांच बार तक अपने-आप फिर से कोशिश की जाती है. इससे, नेटवर्क की गड़बड़ियों या किसी बाहरी सेवा में अस्थायी तौर पर होने वाली रुकावट जैसी अस्थायी गड़बड़ियों को कम करने में मदद मिलती है.

  • retryConfig.minBackoffSeconds=60: हर टास्क के लिए, हर कोशिश के बाद कम से कम 60 सेकंड के अंतराल पर फिर से कोशिश की जाती है. इससे, हर कोशिश के बीच ज़्यादा समय मिलता है. इसलिए, पांच बार फिर से कोशिश करने की सीमा को बहुत जल्दी खत्म नहीं किया जाता.

  • rateLimits.maxConcurrentDispatch=6: किसी भी समय, ज़्यादा से ज़्यादा छह टास्क भेजे जा सकते हैं. इससे, मुख्य फ़ंक्शन को अनुरोधों की एक स्थिर स्ट्रीम मिलती है. साथ ही, चालू इंस्टेंस और कोल्ड स्टार्ट की संख्या कम करने में मदद मिलती है.

टास्क क्यू फ़ंक्शन की जांच करना

ज़्यादातर मामलों में, Cloud Functions एम्युलेटर टास्क क्यू फ़ंक्शन की जांच करने के लिए सबसे अच्छा तरीका है. टास्क क्यू फ़ंक्शन के इम्यूलेशन के लिए, अपने ऐप्लिकेशन को इंस्ट्रुमेंट करने का तरीका जानने के लिए, Emulator Suite का दस्तावेज़ देखें.

इसके अलावा, टास्क क्यू फ़ंक्शन को Firebase Local Emulator Suite में, सामान्य एचटीटीपी फ़ंक्शन के तौर पर दिखाया जाता है. इम्यूलेट किए गए टास्क फ़ंक्शन की जांच करने के लिए, JSON डेटा पेलोड के साथ एचटीटीपी POST अनुरोध भेजा जा सकता है:

 # start the Local Emulator Suite
 firebase emulators:start

 # trigger the emulated task queue function
 curl \
  -X POST                                            # An HTTP POST request...
  -H "content-type: application/json" \              # ... with a JSON body
  http://localhost:$PORT/$PROJECT_ID/$REGION/$NAME \ # ... to function url
  -d '{"data": { ... some data .... }}'              # ... with JSON encoded data

टास्क क्यू फ़ंक्शन डिप्लॉय करना

CLI का इस्तेमाल करके, टास्क क्यू फ़ंक्शन डिप्लॉय करें:Firebase

$ firebase deploy --only functions:backupapod

टास्क क्यू फ़ंक्शन को पहली बार डिप्लॉय करने पर, CLI, Cloud Tasks में एक टास्क क्यू बनाता है. इसमें आपके सोर्स कोड में बताई गई रेट लिमिट और फिर से कोशिश करने के विकल्प शामिल होते हैं.

अगर फ़ंक्शन डिप्लॉय करते समय, आपको अनुमतियों से जुड़ी गड़बड़ियां दिखती हैं, तो पक्का करें कि डिप्लॉयमेंट कमांड चलाने वाले उपयोगकर्ता को, सही IAM की भूमिकाएं असाइन की गई हों.

टास्क क्यू फ़ंक्शन को क्यू में जोड़ना

टास्क क्यू फ़ंक्शन को Cloud Tasks में, भरोसेमंद सर्वर एनवायरमेंट से क्यू में जोड़ा जा सकता है. जैसे, Cloud Functions for Firebase. इसके लिए, Firebase Admin SDK for Node.js या Python के लिए Google Cloud लाइब्रेरी का इस्तेमाल किया जा सकता है. अगर Admin SDK आपके लिए नया है, तो शुरू करने के लिए, सर्वर में Firebase जोड़ना लेख पढ़ें.

आम तौर पर, एक फ़्लो में नया टास्क बनाया जाता है, उसे Cloud Tasks में क्यू में जोड़ा जाता है, और टास्क के लिए कॉन्फ़िगरेशन सेट किया जाता है:

Node.js

exports.enqueuebackuptasks = onRequest(
    async (_request, response) => {
      const queue = getFunctions().taskQueue("backupapod");
      const targetUri = await getFunctionUrl("backupapod");

      const enqueues = [];
      for (let i = 0; i <= BACKUP_COUNT; i += 1) {
        const iteration = Math.floor(i / HOURLY_BATCH_SIZE);
        // Delay each batch by N * hour
        const scheduleDelaySeconds = iteration * (60 * 60);

        const backupDate = new Date(BACKUP_START_DATE);
        backupDate.setDate(BACKUP_START_DATE.getDate() + i);
        // Extract just the date portion (YYYY-MM-DD) as string.
        const date = backupDate.toISOString().substring(0, 10);
        enqueues.push(
            queue.enqueue({date}, {
              scheduleDelaySeconds,
              dispatchDeadlineSeconds: 60 * 5, // 5 minutes
              uri: targetUri,
            }),
        );
      }
      await Promise.all(enqueues);
      response.sendStatus(200);
    });

Python

@https_fn.on_request()
def enqueuebackuptasks(_: https_fn.Request) -> https_fn.Response:
    """Adds backup tasks to a Cloud Tasks queue."""
    task_queue = functions.task_queue("backupapod")
    target_uri = get_function_url("backupapod")

    for i in range(BACKUP_COUNT):
        batch = i // HOURLY_BATCH_SIZE

        # Delay each batch by N hours
        schedule_delay = timedelta(hours=batch)
        schedule_time = datetime.now() + schedule_delay

        dispatch_deadline_seconds = 60 * 5  # 5 minutes

        backup_date = BACKUP_START_DATE + timedelta(days=i)
        body = {"data": {"date": backup_date.isoformat()[:10]}}
        task_options = functions.TaskOptions(
            schedule_time=schedule_time,
            dispatch_deadline_seconds=dispatch_deadline_seconds,
            uri=target_uri,
        )
        task_queue.enqueue(body, task_options)
    return https_fn.Response(status=200, response=f"Enqueued {BACKUP_COUNT} tasks")
  • सैंपल कोड में, टास्क के एक्ज़ीक्यूशन को अलग-अलग समय पर करने की कोशिश की जाती है. इसके लिए, Nवें टास्क के लिए N मिनट की देरी सेट की जाती है. इसका मतलब है कि हर मिनट में एक टास्क ट्रिगर किया जाता है. ध्यान दें कि अगर आपको Cloud Tasks से किसी टास्क को किसी खास समय पर ट्रिगर कराना है, तो scheduleTime (Node.js) या schedule_time (Python) का भी इस्तेमाल किया जा सकता है.

  • सैंपल कोड में, ज़्यादा से ज़्यादा समय सेट किया जाता है. इस समय तक Cloud Tasks किसी टास्क के पूरा होने का इंतज़ार करेगा. Cloud Tasks क्यू के फिर से कोशिश करने के कॉन्फ़िगरेशन के मुताबिक या इस समयसीमा तक टास्क के लिए फिर से कोशिश करेगा. सैंपल में, क्यू को टास्क के लिए पांच बार तक फिर से कोशिश करने के लिए कॉन्फ़िगर किया गया है. हालांकि, अगर पूरी प्रोसेस (फिर से कोशिश करने की कोशिशों के साथ) में पांच मिनट से ज़्यादा समय लगता है, तो टास्क अपने-आप रद्द हो जाता है.

समस्या का हल

Cloud Tasks की लॉगिंग चालू करना

Cloud Tasks के लॉग में, काम की डायग्नोस्टिक जानकारी शामिल होती है. जैसे, किसी टास्क से जुड़े अनुरोध की स्थिति. डिफ़ॉल्ट रूप से, Cloud Tasks के लॉग बंद होते हैं. इसकी वजह यह है कि यह आपके प्रोजेक्ट पर बड़ी संख्या में लॉग जनरेट कर सकता है. हमारा सुझाव है कि टास्क क्यू फ़ंक्शन को डेवलप और डीबग करते समय, डीबग लॉग चालू करें. लॉगिंग चालू करना लेख देखें.

IAM की अनुमतियां

टास्क को क्यू में जोड़ते समय या Cloud Tasks के टास्क क्यू फ़ंक्शन को कॉल करने की कोशिश करते समय, आपको PERMISSION DENIED गड़बड़ियां दिख सकती हैं. पक्का करें कि आपके प्रोजेक्ट में, IAM की ये बाइंडिंग मौजूद हों:

  • Cloud Tasks में टास्क को क्यू में जोड़ने के लिए इस्तेमाल की जाने वाली आइडेंटिटी के पास, Cloud Tasks IAM की अनुमति होनी चाहिए.cloudtasks.tasks.create

    सैंपल में, यह App Engine डिफ़ॉल्ट सेवा खाता है

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • Cloud Tasks में टास्क को क्यू में जोड़ने के लिए इस्तेमाल की जाने वाली आइडेंटिटी के पास, Cloud Tasks में किसी टास्क से जुड़े सेवा खाते का इस्तेमाल करने की अनुमति होनी चाहिए.

    सैंपल में, यह App Engine डिफ़ॉल्ट सेवा खाता है.

Google Cloud IAM दस्तावेज़ में, App Engine डिफ़ॉल्ट सेवा खाते को, App Engine डिफ़ॉल्ट सेवा खाते के उपयोगकर्ता के तौर पर जोड़ने के तरीके के बारे में निर्देश देखें.

  • टास्क क्यू फ़ंक्शन को ट्रिगर करने के लिए इस्तेमाल की जाने वाली आइडेंटिटी के पास, cloudfunctions.functions.invoke अनुमति होनी चाहिए.

    सैंपल में, यह App Engine डिफ़ॉल्ट सेवा खाता है

gcloud functions add-iam-policy-binding $FUNCTION_NAME \
  --region=us-central1 \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudfunctions.invoker