স্ট্যাটিক সাইট এখন পুনঃপ্রকাশের সময়ও চালু থাকে
Mythex-এ স্ট্যাটিক সাইট পুনঃপ্রকাশ করলে আগে লাইভ ফাইলগুলো মুছে ফেলা হতো, তারপর নতুন বিল্ড আপলোড হতো। আপলোড চলাকালীন কিছু ভিজিটর ৪০৪ পেজ দেখতেন, অথবা এমন পেজ পেতেন যার স্ক্রিপ্ট পাওয়া যেত না। আপলোড ব্যর্থ হলে সাইট খালি থেকে যেত, অথবা অর্ধেক নতুন অবস্থায় থাকত। এখন নতুন বিল্ড পুরনোটির উপরে লেখা হয়, পেজগুলো সবশেষে যায়, আর অপ্রয়োজনীয় ফাইল কয়েক মিনিট পরে মুছে ফেলা হয়। দ্বিতীয় একটি পরিবর্তনে পুনঃপ্রকাশ এক মিনিটের বদলে কয়েক সেকেন্ডে দেখা যায় — তবে লোগোর মতো ফাইলের ক্ষেত্রে এক দিন পর্যন্ত লাগতে পারে।
স্ট্যাটিক সাইট কীভাবে পরিবেশিত হয়
স্ট্যাটিক সাইট হলো শুধু ফাইলের সমষ্টি: HTML পেজ, JavaScript, CSS, ছবি। Mythex-এ এমন সাইট প্রকাশ করলে আমরা সেটি বিল্ড করি, আউটপুট আপলোড করি একটি অবজেক্ট স্টোরেজে আপনার সাইটের জন্য আলাদা ফোল্ডারে, এবং একটি এজ নেটওয়ার্কের মাধ্যমে পরিবেশন করি। এজ হলো আপনার ভিজিটরদের কাছাকাছি থাকা সার্ভার, যা স্টোরেজ থেকে ফাইল এনে কিছু সময়ের জন্য কপি রেখে দেয়। (ধারণাটি নতুন হলে, CDN কী গাইডটি এটি ব্যাখ্যা করে।)
দুটি বিষয় ভুল ছিল: পুনঃপ্রকাশে ফাইলগুলো কোন ক্রমে বদলাত, এবং পুরনো কপি কতক্ষণ রাখা হতো।
সমস্যা ১: আপলোড আগে সাইটটি খালি করে ফেলত
পুনঃপ্রকাশে সাইটের ফোল্ডারের সবকিছু মুছে তারপর নতুন বিল্ড আপলোড হতো। আপলোড যতক্ষণ চলত — আমাদের স্থানীয় পরীক্ষায় ২৫০ ফাইলের একটি সাইটের জন্য ১২ সেকেন্ড — যে ভিজিটরের অনুরোধ এজে আগে থেকে ক্যাশ করা ছিল না, তিনি ৪০৪ পেতেন, অথবা এমন HTML পেজ পেতেন যার স্ক্রিপ্টগুলো ৪০৪ ফেরত দিচ্ছিল।
ব্যর্থ আপলোড আরও খারাপ ছিল। ফোল্ডার তখন আগেই খালি, আর দুটি আপলোড পথের একটিতে নতুন index.html ব্যর্থ ফাইলের আগেই পৌঁছে যেতে পারত। ব্যর্থ বলে জানানো পুনঃপ্রকাশের পরেও অর্ধেক-নতুন সাইট লাইভ থাকতে পারত।
সমাধান: উপরে লেখা, পেজ সবশেষে, অবশিষ্ট ফাইল পরে মোছা
- আগে মোছা নয়। নতুন বিল্ড পুরনোটির উপরে আপলোড হয়।
- অ্যাসেট আগে, পেজ পরে। একটি পেজ কোন স্ক্রিপ্ট ও স্টাইল লাগবে তা উল্লেখ করে, তাই পেজগুলো সবশেষে যায়। নতুন পেজ না পৌঁছানো পর্যন্ত ভিজিটর পুরনো পেজ পান, যেটি পুরনো অ্যাসেটের নাম বলে, আর সেগুলো তখনও বিদ্যমান। নতুন পেজ পৌঁছালে, সেগুলো যে নতুন অ্যাসেটের নাম বলে সেগুলো ইতিমধ্যে জায়গায় থাকে।
- অবশিষ্ট ফাইল পরে মোছা। আপলোডের আগে আমরা তালিকা নিই সাইটটি কী কী ফাইল নিয়ে গঠিত। সফল আপলোডের তিন মিনিট পরে, ওই তালিকার যেসব ফাইল নতুন বিল্ড পুনরায় লেখেনি সেগুলো মুছে ফেলা হয়। তিন মিনিট হলো এজ ও ব্রাউজারে পেজ ৬০ সেকেন্ড ক্যাশ থাকতে পারার চেয়ে বেশি, তাই পুরনো পেজ ধরে রাখা ভিজিটর তার অ্যাসেটগুলো এখনও পেতে পারেন।
- সন্দেহ হলে কিছু মুছবেন না। আপলোডের আগের তালিকা ব্যর্থ হলে কিছুই মোছা হয় না। অবশিষ্ট ফাইল ক্ষতিকর নয়, পরের পুনঃপ্রকাশে সেগুলো পরিষ্কার হয়। না জেনে মুছলেই সাইট খালি হয়ে যায়।
একটি ব্যর্থ আপলোডের পর এখন পূর্বের সাইট ঠিক আগের মতোই থাকে।
আমরা এটি স্থানীয়ভাবে শুরু থেকে শেষ পর্যন্ত পরীক্ষা করেছি: প্রকৃত আপলোড স্ক্রিপ্ট, প্রকৃত আপলোড রুট ও স্টোরেজ পরিবেশনা ব্যবহার করে, এবং ঠান্ডা এজ ক্যাশসহ ভিজিটর নিয়ে। পুরনো কোডে পুনঃপ্রকাশের সময় ৯১টির মধ্যে ৫৫ ভিজিট ভাঙা ছিল, আর ব্যর্থ পুনঃপ্রকাশে ৯২টির মধ্যে ৬১। নতুন কোডে, আপলোডের দুটি পথ, একটি ব্যর্থ আপলোড এবং তার পরের পুনঃপ্রকাশ মিলিয়ে প্রায় ৩,৫০০ ভিজিটে ০ ভাঙা ছিল — আর ঠিক অবশিষ্ট ফাইলগুলোই মোছা হয়েছে।
সমস্যা ২: পুনঃপ্রকাশ দেখাতে বেশি সময় লাগত
আপলোড ঠিকঠাক হলেও পরিবর্তন দেরিতে দেখা যেত। এজ একটি পেজের কপি ৬০ সেকেন্ড এবং অন্য প্রতিটি ফাইলের কপি এক দিন রাখত, আর ব্রাউজারকেও একই নিয়ম জানাত। logo.png, ফন্ট, বা public/ ফোল্ডারের যেকোনো ফাইল — যার নাম স্থির — পুনঃপ্রকাশের পরেও এক দিন পর্যন্ত পুরনো সংস্করণ দেখাতে পারত।
সমাধান: বিল্ডের অধীনে ফাইল-কপি
এজ যখন আমাদের API-কে জিজ্ঞেস করে সাইটটি কোথায় আছে, উত্তরে এখন একটি বিল্ড মার্কার থাকে যা প্রতিটি সফল পুনঃপ্রকাশে বদলায়। এজ তার কপিগুলো এই মার্কারের অধীনে রাখে। ফলে এজের ৩০-সেকেন্ডের লুকআপের মেয়াদ শেষ হলেই একটি পুনঃপ্রকাশ একেবারে নতুন ক্যাশ কী-এর সেট হয়ে যায়। পুরনো কপি আর কখনো খুঁজে পাওয়া যায় না, তাই এজ এক দিন পর্যন্ত কপি রাখতে পারে, এবং যে পুনঃপ্রকাশ সেগুলো বদলেছে তার আগের সংস্করণ কখনো পরিবেশন করে না।
ব্রাউজারের জন্য দুটি আলাদা নিয়ম আছে:
- হ্যাশ করা বিল্ড আউটপুট — যেমন
assets/index-CzLcxDO8.js, যার নাম বিষয়বস্তু বদলালে বদলায় — এক বছরের জন্য ক্যাশ হয় এবং immutable চিহ্নিত থাকে। ওই নামে এটি কখনো পুরনো হতে পারে না। - বাকি সবকিছু — পেজ ও লোগোর মতো স্থির নামের ফাইল —
no-cacheচিহ্নিত, অর্থাৎ ব্যবহারের আগে যাচাই করা হয়। কিছু না বদলালে উত্তর একটি ছোট304 Not Modified, কোনো বডি ছাড়া, কারণ এখন আমরা ব্রাউজারেরIf-None-Matchযাচাই মেনে চলি।
দুটিকে আলাদা করতে সতর্কতা লাগে: public/assets/ থেকে কপি করা ফাইল তার নিজের নাম রাখে, আর assets/logo.png এক বছরের জন্য ক্যাশ করলে পুরনো লোগো এক বছর আটকে থাকত। তাই কোনো ফাইলকে তখনই হ্যাশ করা ধরা হয় যখন সেটি কোনো বিল্ড আউটপুট ফোল্ডারে থাকে এবং তার নামে সাধারণ শব্দের বদলে হ্যাশের মতো দেখতে একটি অংশ থাকে।
স্থানীয়ভাবে নতুন পেজ ও লোগো পুনঃপ্রকাশ লাইভ হওয়ার ৬ সেকেন্ড পরে দেখা গেছে। আগে পেজের জন্য ৬০ সেকেন্ড ও লোগোর জন্য এক দিন লাগত।
পথে আরও দুটি ছোট সংশোধন
- HEAD অনুরোধ থেকে ফাঁকা পেজ।
HEADঅনুরোধ শুধু পেজের হেডার চায়, বডি ছাড়া। আমরা সেই ফাঁকা উত্তর ক্যাশ করছিলাম, ফলে পরের ভিজিটর ফাঁকা পেজ পেতেন। এখনHEADউত্তর আর ক্যাশ হয় না। - "এখানে কিছু নেই" এর জন্য সঠিক পেজ। যে ঠিকানায় কোনো অ্যাপ নেই, সেখানে আগে ৫০২ কোডসহ সাধারণ টেক্সট আসত: "This published app is offline or the link was not found"। এখন মালিকের জন্য Mythex-এ ফেরার পথসহ একটি যথাযথ পেজ আসে, শিরোনাম "There's no app here", স্ট্যাটাস ৪০৪। অজানা কাস্টম ডোমেইনও একই পেজ পায়।
আমরা যা শিখেছি
- ক্রম সঠিকতার অংশ। একই ফাইল ভিন্ন ক্রমে আপলোড হলে একটি ভাঙা ও একটি কার্যকর সাইটের মধ্যে পার্থক্য হয়।
- দেরিতে মুছুন, এবং যা জানেন শুধু তাই। আপলোডের আগের তালিকা দিয়ে মোছা নিরাপদ; ফোল্ডার খালি করে আপলোড শেষ হবে আশা করা নিরাপদ নয়।
- সময় দিয়ে নয়, সংস্করণ দিয়ে ক্যাশ করুন। মেয়াদের সময় হলো কখন বিষয়বস্তু বদলাবে তার অনুমান। বিল্ডের সঙ্গে বদলানো কী একটি তথ্য।
সংশ্লিষ্ট: আপনার প্রকাশিত অ্যাপ এখন পুনঃপ্রকাশের সময়ও চালু থাকে। প্রকাশ নিয়ে আরও তথ্যের জন্য ডক্স দেখুন.