এই ডকুমেন্টটিতে বর্ণনা করা হয়েছে, কীভাবে আপনি অ্যাসিঙ্ক্রোনাস (নন-HTTPS) ব্যাকগ্রাউন্ড ফাংশনগুলোকে ব্যর্থ হলে পুনরায় চেষ্টা করার জন্য অনুরোধ করতে পারেন।
কেন ইভেন্ট-চালিত ফাংশনগুলি সম্পূর্ণ হতে ব্যর্থ হয়
বিরল ক্ষেত্রে, অভ্যন্তরীণ ত্রুটির কারণে কোনো ফাংশন সময়ের আগেই বন্ধ হয়ে যেতে পারে, এবং ডিফল্টরূপে ফাংশনটি স্বয়ংক্রিয়ভাবে পুনরায় চেষ্টা করা হতেও পারে বা নাও হতে পারে।
সাধারণত, ফাংশন কোডের মধ্যেই ত্রুটি দেখা দেওয়ার কারণে একটি ইভেন্ট-ড্রাইভেন ফাংশন সফলভাবে সম্পন্ন হতে ব্যর্থ হতে পারে। এমনটা ঘটার কারণগুলোর মধ্যে রয়েছে:
- ফাংশনটিতে একটি বাগ রয়েছে এবং রানটাইম একটি এক্সেপশন থ্রো করে।
- ফাংশনটি কোনো সার্ভিস এন্ডপয়েন্টে পৌঁছাতে পারছে না, অথবা পৌঁছানোর চেষ্টা করার সময় টাইম আউট হয়ে যাচ্ছে।
- ফাংশনটি ইচ্ছাকৃতভাবে একটি এক্সেপশন থ্রো করে (উদাহরণস্বরূপ, যখন কোনো প্যারামিটার ভ্যালিডেশনে ব্যর্থ হয়)।
- একটি Node.js ফাংশন একটি রিজেক্টেড প্রমিজ রিটার্ন করে, অথবা কোনো কলব্যাকে একটি নন-
nullভ্যালু পাস করে।
উপরোক্ত যেকোনো ক্ষেত্রে, ফাংশনটি কার্যকর হওয়া বন্ধ করে দেবে এবং একটি ত্রুটি ফেরত দেবে। যে ইভেন্ট ট্রিগারগুলো বার্তা তৈরি করে, সেগুলোর পুনঃপ্রচেষ্টা নীতি (retry policies) থাকে যা আপনি আপনার ফাংশনের প্রয়োজন অনুযায়ী কাস্টমাইজ করতে পারেন।
পুনরায় চেষ্টার শব্দার্থবিদ্যা
Cloud Functions একটি ইভেন্ট সোর্স থেকে নির্গত প্রতিটি ইভেন্টের জন্য ইভেন্ট-চালিত ফাংশনের অন্তত একবার এক্সিকিউশন নিশ্চিত করে। ডিফল্টরূপে, যদি কোনো ফাংশন ইনভোকেশন একটি ত্রুটির সাথে শেষ হয়, তবে ফাংশনটি পুনরায় ইনভোক করা হয় না এবং ইভেন্টটি বাদ দেওয়া হয়। যখন আপনি একটি ইভেন্ট-চালিত ফাংশনে রিট্রাই সক্ষম করেন, তখন Cloud Functions একটি ব্যর্থ ফাংশন ইনভোকেশনকে ততক্ষণ পর্যন্ত পুনরায় চেষ্টা করে যতক্ষণ না এটি সফলভাবে সম্পন্ন হয় বা রিট্রাই উইন্ডোর মেয়াদ শেষ হয়।
যখন কোনো ফাংশনের জন্য রিট্রাই (retries) সক্রিয় করা থাকে না, যা ডিফল্টভাবে চালু থাকে, তখন ফাংশনটি সর্বদা রিপোর্ট করে যে এটি সফলভাবে সম্পাদিত হয়েছে এবং এর লগগুলিতে 200 OK রেসপন্স কোড দেখা যেতে পারে। ফাংশনটিতে কোনো ত্রুটি ঘটলেও এটি ঘটে। আপনার ফাংশনে কখন ত্রুটি ঘটছে তা স্পষ্ট করার জন্য, ত্রুটিগুলি যথাযথভাবে রিপোর্ট করা নিশ্চিত করুন।
আপনার ফাংশন কোড থেকে রিট্রাই কনফিগার করুন।
Cloud Functions for Firebase ব্যবহার করে, আপনি কোনো ফাংশনের কোডে রিট্রাই (retries) চালু করতে পারেন। নতুন Firestore ডকুমেন্ট তৈরির মতো কোনো ব্যাকগ্রাউন্ড ইভেন্টের জন্য এটি করতে, failurePolicy (1st gen) অথবা retry policy (2nd gen) অপশনটিকে true তে সেট করুন:
প্রথম প্রজন্ম
exports.docCreated = functions
.runWith({
// retry on failure
failurePolicy: true,
})
.firestore.document("my-collection/{docId}")
.onCreate((change, context) => {
/* ... */
});
২য় প্রজন্ম
const { onDocumentCreated } = require("firebase-functions/firestore");
exports.docCreated = onDocumentCreated(
{
// retry on failure
retry: true,
},
"my-collection/{docId}",
(event) => {
/* ... */
},
);
দেখানো অনুযায়ী true সেট করলে, কোনো ফাংশন ব্যর্থ হলে পুনরায় চেষ্টা করার জন্য কনফিগার করা হয়।
পুনরায় চেষ্টার উইন্ডো
দ্বিতীয় প্রজন্মের ফাংশনগুলির জন্য, এই রিট্রাই উইন্ডোটি ২৪ ঘন্টা পর শেষ হয়ে যায়। প্রথম প্রজন্মের ফাংশনগুলির জন্য, এটি ৭ দিন পর শেষ হয়ে যায়। Cloud Functions একটি এক্সপোনেনশিয়াল ব্যাকঅফ কৌশল ব্যবহার করে নতুন তৈরি ইভেন্ট-ড্রাইভেন ফাংশনগুলিকে পুনরায় চেষ্টা করে, যেখানে ব্যাকঅফের সময় ১০ থেকে ৬০০ সেকেন্ডের মধ্যে বৃদ্ধি পায়। এই নীতিটি নতুন ফাংশনগুলিতে প্রথমবার ডিপ্লয় করার সময় প্রয়োগ করা হয়। এই রিলিজ নোটে বর্ণিত পরিবর্তনগুলি কার্যকর হওয়ার আগে প্রথমবার ডিপ্লয় করা বিদ্যমান ফাংশনগুলিতে এটি পূর্ববর্তীভাবে প্রয়োগ করা হয় না, এমনকি যদি আপনি ফাংশনগুলি পুনরায় ডিপ্লয় করেন তবুও।সর্বোত্তম অনুশীলন
এই অংশে রিট্রাই ব্যবহারের সর্বোত্তম পদ্ধতি বর্ণনা করা হয়েছে।
ক্ষণস্থায়ী ত্রুটি সামলাতে রিট্রাই ব্যবহার করুন
যেহেতু আপনার ফাংশনটি সফলভাবে কার্যকর না হওয়া পর্যন্ত ক্রমাগত রিট্রাই করা হয়, তাই রিট্রাই চালু করার আগে টেস্টিংয়ের মাধ্যমে আপনার কোড থেকে বাগের মতো স্থায়ী ত্রুটিগুলো দূর করা উচিত। রিট্রাই সবচেয়ে ভালোভাবে ব্যবহার করা হয় সেইসব সবিস্তার বা ক্ষণস্থায়ী ব্যর্থতা সামাল দেওয়ার জন্য, যেগুলো পুনরায় চেষ্টা করলে সমাধান হওয়ার সম্ভাবনা বেশি থাকে; যেমন একটি অস্থিতিশীল সার্ভিস এন্ডপয়েন্ট বা টাইমআউট।
অসীম পুনরাবৃত্তি এড়াতে একটি সমাপ্তি শর্ত নির্ধারণ করুন।
রিট্রাই ব্যবহার করার সময় আপনার ফাংশনকে একটানা লুপ থেকে রক্ষা করাই সর্বোত্তম পন্থা। ফাংশনটি প্রসেসিং শুরু করার আগে একটি সুনির্দিষ্ট সমাপ্তি শর্ত অন্তর্ভুক্ত করার মাধ্যমে আপনি এটি করতে পারেন। মনে রাখবেন যে, এই কৌশলটি কেবল তখনই কাজ করে যখন আপনার ফাংশনটি সফলভাবে শুরু হয় এবং সমাপ্তি শর্তটি মূল্যায়ন করতে সক্ষম হয়।
একটি সহজ অথচ কার্যকর উপায় হলো একটি নির্দিষ্ট সময়ের চেয়ে পুরোনো টাইমস্ট্যাম্পযুক্ত ইভেন্টগুলো বাদ দেওয়া। ব্যর্থতাগুলো যদি দীর্ঘস্থায়ী বা প্রত্যাশার চেয়ে বেশি সময় ধরে চলে, তবে এটি অতিরিক্ত এক্সিকিউশন এড়াতে সাহায্য করে।
উদাহরণস্বরূপ, এই কোড স্নিপেটটি ১০ সেকেন্ডের চেয়ে পুরোনো সমস্ত ইভেন্ট বাতিল করে দেয়:
const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
callback();
return;
}
Promises-এর সাথে catch ব্যবহার করুন
আপনার ফাংশনে যদি রিট্রাই (retries) সক্রিয় করা থাকে, তাহলে যেকোনো অনিয়ন্ত্রিত ত্রুটি (unhandled error) একটি রিট্রাই (retry) শুরু করবে। নিশ্চিত করুন যে আপনার কোড এমন সব ত্রুটি ক্যাপচার করে, যেগুলোর ফলে রিট্রাই হওয়া উচিত নয়।
আপনার যা করা উচিত তার একটি উদাহরণ নিচে দেওয়া হলো:
return doFooAsync().catch((err) => {
if (isFatal(err)) {
console.error(`Fatal error ${err}`);
}
return Promise.reject(err);
});
পুনরায় চেষ্টাযোগ্য ইভেন্ট-চালিত ফাংশনগুলিকে আইডম্পোটেন্ট করুন
ইভেন্ট-চালিত ফাংশন যা পুনরায় চেষ্টা করা যায়, তা অবশ্যই আইডম্পোটেন্ট হতে হবে। এই ধরনের একটি ফাংশনকে আইডম্পোটেন্ট করার জন্য এখানে কিছু সাধারণ নির্দেশিকা দেওয়া হলো:
- অনেক এক্সটার্নাল এপিআই (যেমন স্ট্রাইপ) আপনাকে প্যারামিটার হিসেবে একটি আইডম্পোটেন্সি কী সরবরাহ করার সুযোগ দেয়। আপনি যদি এই ধরনের কোনো এপিআই ব্যবহার করেন, তবে আপনার ইভেন্ট আইডি-কেই আইডম্পোটেন্সি কী হিসেবে ব্যবহার করা উচিত।
- আইডম্পোটেন্সি অ্যাট-লিস্ট-ওয়ান্স ডেলিভারির সাথে ভালোভাবে কাজ করে, কারণ এটি পুনরায় চেষ্টা করাকে নিরাপদ করে তোলে। তাই নির্ভরযোগ্য কোড লেখার জন্য একটি সাধারণ উত্তম অনুশীলন হলো আইডম্পোটেন্সির সাথে রিট্রাইয়ের সমন্বয় করা।
- আপনার কোডটি যেন অভ্যন্তরীণভাবে আইডম্পোটেন্ট হয়, তা নিশ্চিত করুন। উদাহরণস্বরূপ:
- নিশ্চিত করুন যে ফলাফল পরিবর্তন না করেই মিউটেশন একাধিকবার ঘটতে পারে।
- স্টেট পরিবর্তন করার আগে একটি ট্রানজ্যাকশনের মধ্যে ডাটাবেসের স্টেট কোয়েরি করুন।
- নিশ্চিত করুন যে সমস্ত পার্শ্ব প্রতিক্রিয়া নিজেরাই আইডম্পোটেন্ট।
- ফাংশনের বাইরে, কোড থেকে স্বাধীনভাবে একটি লেনদেনমূলক যাচাই আরোপ করুন। উদাহরণস্বরূপ, কোনো একটি নির্দিষ্ট ইভেন্ট আইডি ইতোমধ্যে প্রক্রিয়া করা হয়েছে—এই তথ্যটি কোথাও সংরক্ষণ করুন।
- ডুপ্লিকেট ফাংশন কলগুলো আলাদাভাবে সমাধান করুন। উদাহরণস্বরূপ, একটি পৃথক পরিষ্করণ প্রক্রিয়া রাখুন যা ডুপ্লিকেট ফাংশন কলগুলোর পরে পরিষ্কার-পরিচ্ছন্নতার কাজ করে।
পুনরায় চেষ্টার নীতি কনফিগার করুন
আপনার ফাংশনের প্রয়োজন অনুসারে, আপনি সরাসরি রিট্রাই পলিসি কনফিগার করতে চাইতে পারেন। এর মাধ্যমে আপনি নিম্নলিখিতগুলির যেকোনো সংমিশ্রণ সেট আপ করতে পারবেন:
- পুনরায় চেষ্টার সময়সীমা ৭ দিন থেকে কমিয়ে মাত্র ১০ মিনিট করুন।
- এক্সপোনেনশিয়াল ব্যাকঅফ রিট্রাই স্ট্র্যাটেজির জন্য সর্বনিম্ন ও সর্বোচ্চ ব্যাকঅফ সময় পরিবর্তন করুন।
- পুনরায় চেষ্টা করার কৌশলটি পরিবর্তন করে অবিলম্বে পুনরায় চেষ্টা করুন।
- একটি অপ্রচলিত বিষয় কনফিগার করুন।
- ডেলিভারি চেষ্টার সর্বোচ্চ এবং সর্বনিম্ন সংখ্যা নির্ধারণ করুন।
রিট্রাই পলিসি কনফিগার করতে:
- একটি HTTP ফাংশন লিখুন।
- ফাংশনের URL-কে টার্গেট হিসেবে উল্লেখ করে Pub/Sub API ব্যবহার করে একটি Pub/Sub সাবস্ক্রিপশন তৈরি করুন।
সরাসরি Pub/Sub কনফিগার করার বিষয়ে আরও তথ্যের জন্য, ব্যর্থতা পরিচালনা সংক্রান্ত Pub/Sub ডকুমেন্টেশন দেখুন।