ফোন ঘুমালেও চ্যাট সচল রাখা
Mythex-এর এজেন্ট একটি অনুরোধে মিনিটের পর মিনিট কাজ করতে পারে, আর আপনি হয়তো ফোন থেকে দেখছেন — যা কাজ চলাকালীন লক হয়, অ্যাপ বদলায়, এবং নেটওয়ার্ক বদলায়। দুটি বাগে সেটি ভুল হতো। একটিতে চ্যাট প্রতিটি “পেজ আবার দৃশ্যমান” সংকেতকে সংযোগ মারা গেছে বলে ধরত, এবং “Connecting…”-এ আটকে যেত। অন্যটিতে, একটি নতুন চ্যাটের প্রথম উত্তরের সময় ঘুমানো ফোনে পরে উত্তরের শুরুর কয়েকটি অংশই ফিরে আসত, ম্যানুয়াল রিফ্রেশ না হওয়া পর্যন্ত। দুটিই ঠিক হয়েছে।
চ্যাট চলমান টার্নকে কীভাবে অনুসরণ করে
এজেন্ট কাজ করার সময় চ্যাট আমাদের সার্ভার থেকে একটি স্ট্রিম খোলা রাখে: প্রতিটি ধাপ — একটি চিন্তা, একটি টুল কল, উত্তরের একটি অংশ — একটি ইভেন্ট হিসেবে আসে। স্ট্রিম বন্ধ হলে চ্যাট পুনরায় সংযোগ করে, এবং সার্ভার সাম্প্রতিক ইভেন্টগুলো আবার পাঠায়, যা শেষ ১২০ সেকেন্ড ধরে রাখে একটি বাফার থেকে। টার্ন শেষ হলে চ্যাট সার্ভারের কাছে সংরক্ষিত ইতিহাসও চায় এবং যা দেখিয়েছিল তার সঙ্গে মিলিয়ে নেয়। এই শেষ ধাপটি স্ট্রিম যা মিস করেছে তা ধরে।
কোনো কিছু না ঘটলেও একটি জীবিত ও মৃত সংযোগ আলাদা করতে সার্ভার প্রতি ১৫ সেকেন্ডে একটি ছোট “পিং” পাঠায়।
বাগ ১: জেগে ওঠা একটি সুস্থ স্ট্রিম মেরে ফেলত
ব্রাউজার পেজকে জানায় যখন সেটি আবার দৃশ্যমান হয়: ট্যাব বদলালে, স্ক্রিন আনলক করলে। আমরা এটিকে সংযোগ পরীক্ষার সংকেত হিসেবে নিতাম — আর বাস্তবে স্ট্রিম বাতিল করে আবার সংযোগ করতাম, ধরে নিয়ে যে লুকানো অবস্থায় সেটি মরে গেছে।
ফোন ও এম্বেডেড ব্রাউজারে এই ইভেন্ট স্ট্রিম মরার চেয়ে অনেক বেশি ঘটে — প্রতি ট্যাব বদলে, প্রতি আনলকে, এবং কিছু এম্বেডেড ব্রাউজারে প্রতি কয়েক সেকেন্ডে। প্রতিটি একটি সম্পূর্ণ সুস্থ স্ট্রিম বাতিল করত। চ্যাট পুনরায় সংযোগ করত, রিপ্লে পেত, আবার বাতিল হতো, এবং শেষে “Connecting…”-এ আটকে থাকত। তারপর বলত টার্ন শেষ হয়েছে, যখন এজেন্ট তখনও কাজ করছে।
সমাধান: স্ট্রিম কথা বলছে কি না, তা দেখে বিচার
চ্যাট এখন প্রতিটি প্রজেক্টের স্ট্রিম শেষ কখন কিছু পেয়েছিল — ইভেন্ট ও ১৫-সেকেন্ডের পিং উভয়ই — তা রেকর্ড করে। “আবার দৃশ্যমান” সংকেত কেবল সেই স্ট্রিমকে বাতিল করে যা ২৫ সেকেন্ড ধরে নীরব: এটি পিং ইন্টারভালের চেয়ে এবং একটি ধীর নেটওয়ার্ক হপের চেয়ে বেশি, তাই একটি জীবিত স্ট্রিম কখনো এই শর্তে পড়ে না। টেস্ট যাচাই করে যে একটি পিং জীবনের লক্ষণ হিসেবে গণ্য হয়, এবং যে স্ট্রিম এইমাত্র পিং করেছে তাকে মৃত ধরা হয় না।
আমরা যে নিয়ম নিয়েছি: একটি পেজের দৃশ্যমানতা পেজ সম্পর্কে বলে, নেটওয়ার্ক সংযোগ সম্পর্কে নয়। সংযোগকেই জিজ্ঞেস করুন।
বাগ ২: ফোন জাগার পরে আধখানা উত্তর
এটি আমরা iOS সিমুলেটরে প্রতিবার পুনরুৎপাদন করতে পারতাম:
- একটি নতুন চ্যাট শুরু করুন এবং এমন একটি অনুরোধ পাঠান যা কিছুক্ষণ নেয়।
- বিল্ডের সময় ফোনকে ঘুমাতে দিন।
- টার্ন শেষ হওয়ার পরে ফিরে আসুন, এবং দুই মিনিটের রিপ্লে বাফার মেয়াদ শেষ হওয়ার পরে।
চ্যাট উত্তরের প্রথম কয়েকটি ব্লক দেখাত, শেষ হয়ে যাওয়া চিহ্নিত — এবং পেজ রিফ্রেশ না করা পর্যন্ত সেভাবেই থাকত।
কেন
একটি নতুন চ্যাটের কোনো থ্রেড — অর্থাৎ সংরক্ষিত কথোপকথন — থাকে না, যতক্ষণ না প্রথম বার্তা সেটি তৈরি করে। সেটি ঘটে send ফাংশনের ভেতরে, তার পরে, যেখানে send আগেই reconcile ধাপটি ধরে রেখেছিল, যা তখনও ভাবছিল কোনো থ্রেড নেই। তাই একটি নতুন চ্যাটের প্রথম টার্নের শেষে reconcile কোনো থ্রেড দেখত না, এবং কিছু না চেয়েই ফিরে যেত।
সাধারণত কেউ লক্ষ করত না, কারণ স্ট্রিম এমনিতেই পুরো টার্নটি পৌঁছে দিত। কিন্তু যে ফোন টার্ন চলাকালীন ঘুমিয়েছিল এবং ১২০ সেকেন্ডের রিপ্লে বাফার মেয়াদ শেষ হওয়ার পরে ফিরে এসেছিল, সে স্ট্রিম থেকে হারানো ইভেন্টগুলো পেতে পারত না — আর যে reconcile ফাঁকটি পূরণ করার কথা ছিল, তা কখনো চলেনি।
সমাধান
- Send reconcile-কে জানায় টার্নটি কোন থ্রেডের, যাতে একটি নতুন চ্যাটের প্রথম টার্নও অন্য যেকোনো টার্নের মতো reconcile হয়। উত্তর ফিরে আসার সময় যদি আপনি অন্য চ্যাট খুলে ফেলেন, ফলাফল ভুল জায়গায় না দেখিয়ে বাদ দেওয়া হয়।
- একটি ব্যর্থ reconcile আবার চেষ্টা হয়। খারাপ সংযোগে জাগা একটি ফোন দেখতে পারে টার্ন শেষ হয়ে গেছে, তারপর সেটি আনতে ব্যর্থ হয়। এখন এটি মনে রাখা হয়, এবং ট্যাব আবার দেখালে বা নেটওয়ার্ক ফিরে এলে চ্যাট আবার চায়।
- “Worked for” সৎ থাকে। প্রতিটি উত্তর দেখায় এজেন্ট কতক্ষণ কাজ করেছে। যদি ট্যাব সার্ভারের শেষ-টার্ন বার্তা কখনো না দেখে থাকে, তবে আগে সেটি Send থেকে নিজের ঘড়ি দিয়ে পূরণ করত — যা ফোন জাগা পর্যন্ত চলত, দূরে থাকার সময়সহ। এখন সেই হিসাবটি অনুমান হিসেবে চিহ্নিত, এবং ইতিহাস এলে সংরক্ষিত সময়কাল দিয়ে প্রতিস্থাপিত হয়।
আমরা যা শিখেছি
- যে ডিভাইসে মানুষ আসলে ব্যবহার করে, সেখানে সেভাবেই পরীক্ষা করুন। দুটি বাগই ছিল “একটি কাজ করা স্ট্রিম” আর “পকেটে থাকা একটি ফোনের” মাঝখানের ফাঁকে।
- যে ফলব্যাক কখনো চলে না, তা প্রকৃত ফলব্যাক নয়। reconcile ধাপটি ঠিক এই ক্ষেত্রটি ধরার জন্যই ছিল, অথচ নীরবে এড়িয়ে যাচ্ছিল।
- পুনরুদ্ধারকেও আবার চেষ্টা করুন। ফোন জাগার মুহূর্তেই প্রায়ই তার সংযোগ সবচেয়ে খারাপ থাকে।
- অনুমানকে তথ্য হিসেবে দেখাবেন না। ভুল ঘড়ির একটি সময়কাল কিছু না থাকার চেয়েও খারাপ; তাকে চিহ্নিত করুন বা প্রতিস্থাপন করুন।
একই কাজ চ্যাটে টার্ন চলাকালীন আপনি যেসব ছোট জিনিস দেখেন তাও গুছিয়েছে: শেল ধাপগুলো এখন cd-এর বদলে যে কমান্ড কাজটি করে তার নামে লেবেল হয়, চ্যাটের স্ক্রিনশট পেজের উপরের-বাঁ অংশ রাখে ও কলামে ফিট করে, আর নতুন প্রজেক্ট রিফ্রেশ ছাড়াই তার তৈরি হওয়া নাম পায়।
আপনি যদি ফোনের জন্য নিজের অ্যাপ বানান, তবে মোবাইল-বান্ধব ওয়েব অ্যাপ কীভাবে বানাবেন এবং নেটিভ বনাম প্রগ্রেসিভ ওয়েব অ্যাপ গাইড দুটি মূল বিষয়গুলো ঢাকে। চ্যাট সম্পর্কে আরও জানতে চ্যাট ডকস দেখুন।