একটি ব্রাউজার-ভিত্তিক Python প্লেগ্রাউন্ড, যা ৫.৫ MB রানটাইম সরবরাহ করে, ধীরগতির সংযোগ ব্যবহারকারী ইউজারদের জন্য নিঃশব্দে (silently) কাজ করা বন্ধ করে দিচ্ছিল। এর কারণ ছিল ভুলভাবে ব্যবহৃত Network Information API এবং একটি এরর-গ্রুপিং ড্যাশবোর্ড যা সমস্যাটিকে ভুলভাবে চিহ্নিত করেছিল। বাগটি কয়েক সপ্তাহ ধরে লুকিয়ে ছিল, ডেভেলপারদের সময় নষ্ট করেছে এবং ব্যবহারকারীদের একটি অংশ কোড চালাতে অক্ষম করে রেখেছিল।
সমস্যাটি কীভাবে সামনে এল
প্লেগ্রাউন্ডের এরর ট্র্যাকার একটি মাত্র নজরকাড়া মেসেজ প্রদর্শন করছিল: “undefined is not an object.” এই শিরোনামটি একটি সাধারণ JavaScript টাইপো নির্দেশ করছিল, তাই টিম একটি অস্তিত্বহীন কোড পাথ (code path) খুঁজতে ব্যস্ত হয়ে পড়ে। যখন তারা র (raw) মেটাডেটা পরীক্ষা করল, তারা দেখল যে ৮৯% ঘটনা আসলে নেটওয়ার্ক টাইমআউট ছিল। ড্যাশবোর্ডটি আসা প্রথম এররটিকে গ্রহণ করেছিল এবং পুরো ব্যাচটির নাম হিসেবে সেটি ব্যবহার করেছিল, যা প্রকৃত ব্যর্থতার ধরনটিকে আড়াল করে রেখেছিল।
শিক্ষা ১ – ড্যাশবোর্ডের শিরোনাম বিভ্রান্তিকর হতে পারে
একটি ড্যাশবোর্ড যা ঘটনাগুলোকে একত্রিত (aggregate) করে, তা কেবল তখনই সহায়ক হয় যদি এর একত্রীকরণ লজিক প্রতিটি ঘটনার প্রকৃত কারণের প্রতিফলন ঘটায়। এখানে, এরর কারণের পরিবর্তে লোকেশন অনুযায়ী গ্রুপ করার ফলে একটি ক্লায়েন্ট-সাইড বাগের ভুল চিত্র ফুটে উঠেছিল। মূল শিক্ষা: শুধুমাত্র একটি ড্যাশবোর্ড হেডলাইনের ওপর ভিত্তি করে কোনো সমস্যা সমাধান করার চেষ্টা করবেন না। রিসোর্স বরাদ্দ করার আগে মূল ঘটনাগুলোর একটি নমুনা সংগ্রহ করুন এবং আসলে কী ঘটছে তা যাচাই করে নিন।
শিক্ষা ২ – প্লেসহোল্ডার ভ্যালু কোনো পরিমাপ নয়
ধীরগতির সংযোগ ব্যবহারকারী ইউজারদের জন্য ভারী রানটাইম লোড করা এড়াতে, কোডটি Network Information API ব্যবহার করে এবং downlink প্রপার্টিটি পড়েছিল, যা প্রতি সেকেন্ডে মেগাবিট (megabits per second) রিপোর্ট করে। প্রথম ভিজিটের ক্ষেত্রে, Chrome প্রায়শই প্রকৃত পরিমাপের পরিবর্তে একটি প্লেসহোল্ডার প্রদান করে। লজিকটি সেই প্লেসহোল্ডারটিকে একটি দ্রুত সংযোগ হিসেবে গণ্য করেছিল এবং অপ্টিমাইজেশনটি বাদ দিয়েছিল, যার ফলে সেই ইউজাররাই বাধাগ্রস্ত হয়েছিল যাদের সাহায্য করার কথা ছিল।
যেকোনো ডিফল্ট বা সেন্টিনেল (sentinel) ভ্যালুকে "কোনো ডেটা নেই" হিসেবে গণ্য করুন। একটি প্লেসহোল্ডার একটি ফলব্যাক (fallback) কৌশল শুরু করার কথা, এটিকে প্রকৃত স্পিড রিডিং হিসেবে ব্যাখ্যা করা উচিত নয়।
শিক্ষা ৩ – নেটওয়ার্কের অবস্থা পরিবর্তনশীল, তাই একটি মাত্র স্ন্যাপশট নির্ভরযোগ্য নয়
downlink সমস্যার পর, টিম effectiveType পরীক্ষা করার দিকে ঝুঁকেছিল, যা সংযোগগুলোকে “4g”, “3g” ইত্যাদি হিসেবে শ্রেণীবদ্ধ করে। একটি দ্রুত ল্যাব টেস্ট সফল হয়েছিল, কিন্তু কিছুক্ষণ পর একই টেস্ট পুনরায় চালালে তা ব্যর্থ হয়েছিল। মোবাইল সংযোগের অবস্থা ওঠানামা করে; একজন ব্যবহারকারী এক সেকেন্ডে দ্রুত 4G লিঙ্কে থাকতে পারেন এবং পরের মুহূর্তেই ধীরগতির 3G-তে নেমে যেতে পারেন। শুধুমাত্র পেজ লোড করার সময় সংযোগ পরীক্ষা করা একটি জুয়া খেলার মতো।
সঠিক পদ্ধতি হলো Network Information অবজেক্টের change ইভেন্টে সাবস্ক্রাইব করা এবং একবারের সিদ্ধান্তের পরিবর্তে ব্যান্ডউইথের যেকোনো পরিবর্তনের সাথে প্রতিক্রিয়া জানানো।
টিম যা পরিবর্তন করেছে
- Two-stage download – রানটাইম এখন একটি ক্ষুদ্র বুটস্ট্র্যাপ (bootstrap) ফাইল দিয়ে শুরু হয়। যদি সংযোগটি ধীরগতির হিসেবে শনাক্ত হয়, তবে বুটস্ট্র্যাপটি ছোট ছোট চাঙ্কে (chunks) বাকি রানটাইমটি সংগ্রহ করে, যা সম্পূর্ণ ডাউনলোড বাতিল হওয়ার সম্ভাবনা কমিয়ে দেয়।
- Live monitoring – শুধুমাত্র একবার
downlinkপড়ার পরিবর্তে, কোডটি এখনchangeইভেন্টগুলো শোনে এবং তাৎক্ষণিকভাবে (on the fly) ডাউনলোড কৌশল পরিবর্তন করে। - Stable source selection – আগে সিস্টেমটি ডাউনলোডের মাঝপথে দ্রুততর এন্ডপয়েন্ট পাওয়া গেলে CDN পরিবর্তন করে ফেলত। ধীরগতির সংযোগে এটি ডাউনলোডকে শূন্য থেকে পুনরায় শুরু করতে বাধ্য করত, যা সমস্যাটিকে আরও বাড়িয়ে তুলত। নতুন লজিকটি ডাউনলোডের পুরো সময়কাল জুড়ে সোর্সটিকে লক করে রাখে।
- Deferred cache writes – অ্যাপটি ব্যবহারযোগ্য হওয়ার আগে যে ভারী ক্যাশ অপারেশনগুলো চলত, সেগুলো এখন রানটাইম শুরু হওয়ার পর পর্যন্ত স্থগিত রাখা হয়, যাতে গুরুত্বপূর্ণ ডাউনলোডের জন্য ব্যান্ডউইথ খালি থাকে।
বৃহত্তর ঝুঁকি
ওয়েব-ভিত্তিক টুল তৈরি করা ডেভেলপারদের জন্য নেটওয়ার্কের পরিবর্তনশীলতা একটি অত্যন্ত গুরুত্বপূর্ণ বিষয়। ধীরগতির সংযোগে একটি নিঃশব্দ ব্যর্থতা ব্যবহারকারীদের হতাশ করে এবং টেলিমেট্রি (telemetry) ডেটাকে বিকৃত করে, যা টিমকে ভুল ডিবাগিং পথে পরিচালিত করে। এই ক্ষেত্রে, ডেটার ভুল ব্যাখ্যা কয়েক সপ্তাহ ধরে নিরর্থক অনুসন্ধানের কারণ হয়েছিল।
পরবর্তীতে যা খেয়াল রাখতে হবে
মূল শিক্ষা: যখন ডেটা খুব বেশি নিখুঁত মনে হয়, তখন সম্ভবত সেটি একটি প্লেসহোল্ডার; যখন একটি ড্যাশবোর্ড হেডলাইন একটি মাত্র বাগের দিকে নির্দেশ করে, তখন আরও গভীরে অনুসন্ধান করুন; এবং যখন আপনি একবারের নেটওয়ার্ক রিডিংয়ের ওপর ভিত্তি করে কোনো সিদ্ধান্ত নেন, তখন আপনি একটি পরিবর্তনশীল লক্ষ্যের ওপর বাজি ধরছেন। এই বাস্তবতার সাথে খাপ খাইয়ে নেওয়াই নিঃশব্দ ব্যর্থতাগুলোকে অনুমানযোগ্য এবং পুনরুদ্ধারযোগ্য ইভেন্টে পরিণত করে।
