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

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

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

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

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

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

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

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

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

टास्क की कतार वाले फ़ंक्शन लिखना

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

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

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

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

$ firebase deploy --only functions:backupapod

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

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

टास्क कतार के फ़ंक्शन को कतार में लगाना

टास्क क्यू फ़ंक्शन को Cloud Tasks में, भरोसेमंद सर्वर एनवायरमेंट जैसे कि Cloud Functions for Firebase से कतार में लगाया जा सकता है. इसके लिए, Node.js के लिए Firebase Admin SDK या 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")
  • इस सैंपल कोड में, टास्क को पूरा करने में लगने वाले समय को कम करने की कोशिश की गई है. इसके लिए, हर टास्क को पूरा करने में लगने वाले समय को कम किया गया है. इसका मतलब है कि हर मिनट में ~ 1 टास्क ट्रिगर होगा. ध्यान दें कि अगर आपको किसी टास्क को तय समय पर ट्रिगर करना है, तो scheduleTime (Node.js) या schedule_time (Python) का भी इस्तेमाल किया जा सकता है.Cloud Tasks

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

समस्या का हल

Cloud Tasks लॉगिंग की सुविधा चालू करना

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

IAM अनुमतियां

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

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

    इस सैंपल में, यह 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 डिफ़ॉल्ट सेवा खाता है.

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

  • टास्क क्यू फ़ंक्शन को ट्रिगर करने के लिए इस्तेमाल की गई पहचान के पास 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