ক্লাউড টাস্কের সাথে সারিবদ্ধ ফাংশন


টাস্ক সারি ফাংশনগুলি Google ক্লাউড টাস্কগুলির সুবিধা গ্রহণ করে আপনার অ্যাপকে আপনার প্রধান অ্যাপ্লিকেশন প্রবাহের বাইরে অ্যাসিঙ্ক্রোনাসভাবে সময়-সাপেক্ষ, সংস্থান-নিবিড় বা ব্যান্ডউইথ-সীমিত কাজগুলি চালাতে সাহায্য করে৷

উদাহরণস্বরূপ, কল্পনা করুন যে আপনি একটি রেট সীমা সহ একটি API এ হোস্ট করা চিত্র ফাইলগুলির একটি বড় সেটের ব্যাকআপ তৈরি করতে চান৷ সেই API-এর একজন দায়িত্বশীল ভোক্তা হওয়ার জন্য, আপনাকে তাদের হারের সীমাকে সম্মান করতে হবে। এছাড়াও, এই ধরনের দীর্ঘমেয়াদী কাজ টাইমআউট এবং মেমরি সীমার কারণে ব্যর্থতার জন্য ঝুঁকিপূর্ণ হতে পারে।

এই জটিলতা প্রশমিত করতে, আপনি একটি টাস্ক কিউ ফাংশন লিখতে পারেন যা scheduleTime এবং dispatchDeadline মতো মৌলিক টাস্ক বিকল্পগুলি সেট করে এবং তারপরে ক্লাউড টাস্কের একটি সারিতে ফাংশনটি হস্তান্তর করে৷ ক্লাউড টাস্ক এনভায়রনমেন্ট বিশেষভাবে ডিজাইন করা হয়েছে কার্যকর কনজেশন কন্ট্রোল নিশ্চিত করার জন্য এবং এই ধরনের ক্রিয়াকলাপগুলির জন্য পুনরায় চেষ্টা করার নীতিগুলি।

Firebase v3.20.1 এর জন্য ক্লাউড ফাংশনগুলির জন্য Firebase SDK এবং টাস্ক সারি ফাংশন সমর্থন করার জন্য Firebase অ্যাডমিন SDK v10.2.0 এবং উচ্চতর এর সাথে ইন্টারঅপারেটিং করে।

ফায়ারবেসের সাথে টাস্ক কিউ ফাংশন ব্যবহার করলে ক্লাউড টাস্ক প্রক্রিয়াকরণের জন্য চার্জ হতে পারে। আরও তথ্যের জন্য ক্লাউড টাস্কের মূল্য দেখুন।

টাস্ক কিউ ফাংশন তৈরি করুন

টাস্ক কিউ ফাংশন ব্যবহার করতে, এই ওয়ার্কফ্লো অনুসরণ করুন:

  1. ক্লাউড ফাংশনের জন্য Firebase SDK ব্যবহার করে একটি টাস্ক কিউ ফাংশন লিখুন।
  2. একটি HTTP অনুরোধের সাথে এটি ট্রিগার করে আপনার ফাংশন পরীক্ষা করুন।
  3. Firebase CLI এর সাথে আপনার ফাংশন স্থাপন করুন। প্রথমবার আপনার টাস্ক কিউ ফাংশন স্থাপন করার সময়, CLI আপনার সোর্স কোডে নির্দিষ্ট বিকল্পগুলি (রেট সীমিত করা এবং পুনরায় চেষ্টা) সহ ক্লাউড টাস্কে একটি টাস্ক সারি তৈরি করবে।
  4. সদ্য নির্মিত টাস্ক সারিতে কাজগুলি যোগ করুন, প্রয়োজনে একটি সম্পাদনের সময়সূচী সেট আপ করতে পরামিতিগুলি বরাবর পাস করুন৷ আপনি অ্যাডমিন SDK ব্যবহার করে কোড লিখে এবং Firebase-এর জন্য ক্লাউড ফাংশনে স্থাপন করে এটি অর্জন করতে পারেন।

টাস্ক কিউ ফাংশন লিখুন

এই বিভাগে কোড নমুনাগুলি এমন একটি অ্যাপের উপর ভিত্তি করে তৈরি করা হয়েছে যা একটি পরিষেবা সেট আপ করে যা NASA-এর Astronomy Picture of the Day থেকে সমস্ত ছবি ব্যাক আপ করে৷ শুরু করতে, প্রয়োজনীয় মডিউল আমদানি করুন:

Node.js

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

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

পাইথন

# 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) => {

পাইথন

@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 : টাস্ক সারিতে থাকা প্রতিটি কাজ স্বয়ংক্রিয়ভাবে 5 বার পর্যন্ত পুনরায় চেষ্টা করা হয়। এটি নেটওয়ার্ক ত্রুটি বা নির্ভরশীল, বাহ্যিক পরিষেবার অস্থায়ী পরিষেবা ব্যাহতের মতো ক্ষণস্থায়ী ত্রুটিগুলি প্রশমিত করতে সহায়তা করে৷

  • retryConfig.minBackoffSeconds=60 : প্রতিটি কাজ প্রতিটি প্রচেষ্টা থেকে কমপক্ষে 60 সেকেন্ডের মধ্যে পুনরায় চেষ্টা করা হয়। এটি প্রতিটি প্রচেষ্টার মধ্যে একটি বড় বাফার প্রদান করে তাই আমরা খুব দ্রুত 5টি পুনঃপ্রচেষ্টা শেষ করার জন্য তাড়াহুড়ো করি না।

  • rateLimits.maxConcurrentDispatch=6 : একটি নির্দিষ্ট সময়ে সর্বাধিক 6টি কাজ পাঠানো হয়। এটি অন্তর্নিহিত ফাংশনে অনুরোধের একটি স্থির প্রবাহ নিশ্চিত করতে সাহায্য করে এবং সক্রিয় দৃষ্টান্ত এবং ঠান্ডা শুরুর সংখ্যা কমাতে সাহায্য করে।

টেস্ট টাস্ক সারি ফাংশন

ফায়ারবেস লোকাল এমুলেটর স্যুটে টাস্ক কিউ ফাংশনগুলি সাধারণ HTTP ফাংশন হিসাবে উন্মুক্ত করা হয়। আপনি একটি JSON ডেটা পেলোড সহ একটি HTTP 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 CLI ব্যবহার করে টাস্ক কিউ ফাংশন স্থাপন করুন:

$ firebase deploy --only functions:backupapod

প্রথমবার একটি টাস্ক কিউ ফাংশন স্থাপন করার সময়, CLI আপনার সোর্স কোডে নির্দিষ্ট বিকল্পগুলি (রেট সীমিত করা এবং পুনরায় চেষ্টা) সহ ক্লাউড টাস্কে একটি টাস্ক সারি তৈরি করে।

ফাংশন স্থাপন করার সময় আপনি যদি অনুমতি ত্রুটির সম্মুখীন হন, তাহলে নিশ্চিত করুন যে যথাযথ IAM ভূমিকাগুলি স্থাপনার কমান্ড চালাচ্ছেন এমন ব্যবহারকারীকে বরাদ্দ করা হয়েছে।

সারিবদ্ধ টাস্ক সারি ফাংশন

টাস্ক সারি ফাংশনগুলি ক্লাউড টাস্কে একটি বিশ্বস্ত সার্ভার পরিবেশ থেকে সারিবদ্ধ করা যেতে পারে যেমন Firebase-এর জন্য ক্লাউড ফাংশন Node.js-এর জন্য Firebase অ্যাডমিন SDK বা Python-এর জন্য Google ক্লাউড লাইব্রেরি ব্যবহার করে৷ আপনি যদি অ্যাডমিন SDK-এ নতুন হয়ে থাকেন, তাহলে শুরু করতে একটি সার্ভারে Firebase যোগ করুন দেখুন।

একটি সাধারণ প্রবাহ একটি নতুন টাস্ক তৈরি করে, এটিকে ক্লাউড টাস্কে সারিবদ্ধ করে এবং টাস্কের জন্য কনফিগারেশন সেট করে:

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

পাইথন

@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")
  • নমুনা কোডটি Nth টাস্কের জন্য Nth মিনিটের বিলম্ব যুক্ত করে কার্য সম্পাদনকে ছড়িয়ে দেওয়ার চেষ্টা করে। এটি ট্রিগারিং ~ 1 টাস্ক/মিনিট অনুবাদ করে৷ মনে রাখবেন যে আপনি যদি ক্লাউড টাস্ক একটি নির্দিষ্ট সময়ে একটি টাস্ক ট্রিগার করতে চান তবে আপনি scheduleTime (Node.js) বা schedule_time (Python) ব্যবহার করতে পারেন।

  • নমুনা কোডটি ক্লাউড টাস্কগুলি একটি টাস্ক সম্পূর্ণ হওয়ার জন্য সর্বোচ্চ কত সময় অপেক্ষা করবে তা সেট করে। ক্লাউড টাস্ক সারির কনফিগারেশনের পরে বা এই সময়সীমায় না পৌঁছানো পর্যন্ত টাস্কটি পুনরায় চেষ্টা করবে। নমুনায়, সারিটি 5 বার পর্যন্ত টাস্কটি পুনরায় চেষ্টা করার জন্য কনফিগার করা হয়েছে, তবে পুরো প্রক্রিয়াটি (পুনরায় চেষ্টা সহ) 5 মিনিটের বেশি সময় লাগলে টাস্কটি স্বয়ংক্রিয়ভাবে বাতিল হয়ে যায়।

পুনরুদ্ধার করুন এবং লক্ষ্য URI অন্তর্ভুক্ত করুন

অন্তর্নিহিত টাস্ক সারি ফাংশনগুলির অনুরোধগুলি প্রমাণীকরণের জন্য ক্লাউড টাস্ক যেভাবে প্রমাণীকরণ টোকেন তৈরি করে, কাজগুলি সারিবদ্ধ করার সময় আপনাকে অবশ্যই ফাংশনের ক্লাউড রান URL নির্দিষ্ট করতে হবে৷ আমরা সুপারিশ করছি যে আপনি প্রোগ্রামেটিকভাবে আপনার ফাংশনের জন্য URL পুনরুদ্ধার করুন যেমনটি নীচে দেখানো হয়েছে:

Node.js

/**
 * Get the URL of a given v2 cloud function.
 *
 * @param {string} name the function's name
 * @param {string} location the function's location
 * @return {Promise<string>} The URL of the function
 */
async function getFunctionUrl(name, location="us-central1") {
  if (!auth) {
    auth = new GoogleAuth({
      scopes: "https://www.googleapis.com/auth/cloud-platform",
    });
  }
  const projectId = await auth.getProjectId();
  const url = "https://cloudfunctions.googleapis.com/v2beta/" +
    `projects/${projectId}/locations/${location}/functions/${name}`;

  const client = await auth.getClient();
  const res = await client.request({url});
  const uri = res.data?.serviceConfig?.uri;
  if (!uri) {
    throw new Error(`Unable to retreive uri for function at ${url}`);
  }
  return uri;
}

পাইথন

def get_function_url(name: str, location: str = SupportedRegion.US_CENTRAL1) -> str:
    """Get the URL of a given v2 cloud function.

    Params:
        name: the function's name
        location: the function's location

    Returns: The URL of the function
    """
    credentials, project_id = google.auth.default(
        scopes=["https://www.googleapis.com/auth/cloud-platform"])
    authed_session = AuthorizedSession(credentials)
    url = ("https://cloudfunctions.googleapis.com/v2beta/" +
           f"projects/{project_id}/locations/{location}/functions/{name}")
    response = authed_session.get(url)
    data = response.json()
    function_url = data["serviceConfig"]["uri"]
    return function_url

সমস্যা সমাধান

ক্লাউড টাস্ক লগিং চালু করুন

ক্লাউড টাস্কের লগগুলিতে একটি টাস্কের সাথে সম্পর্কিত অনুরোধের স্থিতির মতো দরকারী ডায়গনিস্টিক তথ্য থাকে। ডিফল্টরূপে, ক্লাউড টাস্ক থেকে লগগুলি বন্ধ হয়ে যায় কারণ এটি আপনার প্রোজেক্টে প্রচুর পরিমাণে লগ তৈরি করতে পারে৷ আপনি যখন আপনার টাস্ক সারি ফাংশন সক্রিয়ভাবে বিকাশ এবং ডিবাগ করছেন তখন আমরা আপনাকে ডিবাগ লগ চালু করার পরামর্শ দিই। লগিং চালু করা দেখুন।

আইএএম অনুমতি

কাজগুলি সারিবদ্ধ করার সময় বা ক্লাউড টাস্কগুলি আপনার টাস্ক কিউ ফাংশনগুলি চালু করার চেষ্টা করার সময় আপনি PERMISSION DENIED ত্রুটি দেখতে পারেন৷ নিশ্চিত করুন যে আপনার প্রকল্পে নিম্নলিখিত IAM বাইন্ডিং আছে:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • ক্লাউড টাস্কে টাস্ক সারিবদ্ধ করার জন্য যে পরিচয়টি ব্যবহার করা হয় তার ক্লাউড টাস্কে একটি টাস্কের সাথে যুক্ত পরিষেবা অ্যাকাউন্ট ব্যবহার করার অনুমতি প্রয়োজন।

    নমুনায়, এটি অ্যাপ ইঞ্জিনের ডিফল্ট পরিষেবা অ্যাকাউন্ট

অ্যাপ ইঞ্জিন ডিফল্ট পরিষেবা অ্যাকাউন্টের ব্যবহারকারী হিসাবে অ্যাপ ইঞ্জিন ডিফল্ট পরিষেবা অ্যাকাউন্ট কীভাবে যুক্ত করবেন তার নির্দেশাবলীর জন্য Google ক্লাউড IAM ডকুমেন্টেশন দেখুন।

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