ব্যর্থ পুনঃপ্রকাশ কখনো চালু থাকা ব্যাকএন্ড মোছে না
২৫ সেপ্টেম্বর একটি ব্যর্থ পুনঃপ্রকাশ একটি অ্যাপের ব্যাকএন্ড মুছে দিয়েছিল, যেটি প্রায় আড়াই ঘণ্টা ধরে চালু ছিল এবং ঠিকভাবে কাজ করছিল। যে কোড ব্যর্থ প্রকাশকে উল্টে দেয়, সে প্রকাশ যে প্রতিটি সার্ভার অ্যাপ ছুঁয়েছিল, সেগুলো সব মুছে ফেলত, এমনকি যেগুলো প্রকাশ শুরু হওয়ার আগেই চালু ছিল। এখন শুধু সেই অ্যাপগুলোই মোছা হয় যেগুলো একটি প্রকাশ নতুন তৈরি করেছে। যে অ্যাপ আগে থেকেই ছিল, সেটিকে ঠিক আগের যে ইমেজে চলছিল, সেখানে ফিরিয়ে আনা হয়। একই দিনে দুটি অনুসরণ-সংশোধন নিশ্চিত করেছে যে হোস্টিং প্ল্যাটফর্মের নিজস্ব ডিপ্লয় টুল ব্যর্থ হলেও এই উল্টে দেওয়া চলে, এবং যে সুস্থ অ্যাপ শুধু ঘুমিয়ে ছিল, তাকে ব্যর্থ ধরা হয় না।
একটি ব্যাকএন্ড কীভাবে প্রকাশ হয়
আপনার Mythex অ্যাপে যদি ব্যাকএন্ড থাকে, অর্থাৎ শুধু স্ট্যাটিক ফাইল নয় বরং একটি API বা সার্ভার, তাহলে প্রকাশের সময় সেটি একটি Dockerfile (অ্যাপটিকে একটি ইমেজে প্যাকেজ করার রেসিপি) থেকে তৈরি হয় এবং আমাদের হোস্টিং প্ল্যাটফর্মের মেশিনগুলোতে সেই ইমেজ ছড়িয়ে দেওয়া হয়। এরপর একটি হেলথ চেক অপেক্ষা করে, নতুন সংস্করণটি সত্যিই উঠে দাঁড়ায় এবং টিকে থাকে কি না, তার পরেই প্রকাশটিকে লাইভ বলে চিহ্নিত করা হয়।
পথে যেকোনো কিছু ব্যর্থ হলে একটি রোলব্যাক চলে, যা সেটিকে উল্টে দেয়। এই রোলব্যাক ঠিকভাবে হওয়া প্রকাশ-প্রক্রিয়ার প্রায় সবকিছুর চেয়ে বেশি গুরুত্বপূর্ণ, কারণ এটি ঠিক তখনই চলে যখন কিছু একটা আগেই ভুল হয়ে গেছে।
সমস্যা ১: রোলব্যাক যা ফেরানোর কথা ছিল, তা মুছে ফেলল
রোলব্যাক একটি তালিকা রাখত যে প্রকাশটি কোন কোন সার্ভার অ্যাপে ডিপ্লয় করেছে, আর ব্যর্থতার সময় তার প্রতিটিকে ধ্বংস করে দিত। প্রথমবার প্রকাশের ক্ষেত্রে এটি সঠিক ছিল: অ্যাপটি কিছুক্ষণ আগেই তৈরি হয়েছে, এর ওপর কিছু নির্ভর করে না, এবং মুছে দিলে সবকিছু আগের অবস্থায় ফিরে যায়।
পুনঃপ্রকাশের ক্ষেত্রে এটি ঠিক উল্টো ভুল। অ্যাপটি আগে থেকেই ছিল এবং প্রকৃত দর্শকদের সেবা দিচ্ছিল। ২৫ সেপ্টেম্বর, একটি অ্যাপের API যা প্রায় আড়াই ঘণ্টা ধরে লাইভ ছিল, একটি ব্যর্থ পুনঃপ্রকাশ তা মুছে ফেলেছিল।
একই কোডে আরেকটি ব্যর্থতার পথ লুকিয়ে ছিল। মোছা না হলে ভাঙা নতুন ইমেজটি মেশিনগুলোতেই থেকে যেত, অথচ আমরা মালিককে জানাতাম যে তার বর্তমান সাইট এখনও লাইভ আছে। হেলথ চেক ব্যর্থ হওয়ার আগেই নতুন ইমেজ প্রতিটি মেশিনে ছড়িয়ে যায়। তাই কিছু না করা আর উল্টে দেওয়া এক জিনিস নয়।
সমাধান: যা তৈরি করেছেন শুধু তা মুছুন, বাকিটা ফেরান
এখন প্রতিটি প্রকাশ, তার স্পর্শ করা প্রতিটি সার্ভার অ্যাপের জন্য নথিবদ্ধ করে:
- এই প্রকাশটি কি সেটি তৈরি করেছে, এবং
- যদি না করে থাকে, তাহলে প্রকাশ শুরুর ঠিক আগে সেটি কোন ইমেজে চলছিল।
ব্যর্থতায় প্রতিটি অ্যাপ তিনটির একটি ব্যবস্থা পায়:
- এই প্রকাশ তৈরি করেছে: আগের মতোই ধ্বংস করা হয়।
- আগে থেকেই ছিল, আগের ইমেজ জানা আছে: একই কনফিগারেশনে আগের ইমেজটি আবার ডিপ্লয় করা হয়। কোনো বিল্ড হয় না, শুধু ইমেজটি ফিরে যায়।
- আগে থেকেই ছিল, আগের ইমেজ অজানা: অ্যাপটি যেমন আছে তেমনই রাখা হয়। বিদ্যমান অ্যাপ কখনো মোছা হয় না, এমনকি যখন সেটি ফেরানো না গেলেও।
এই নিয়মগুলো একটি ছোট, বিশুদ্ধ ফাংশন, যার নিজস্ব টেস্ট আছে। ফলে সিদ্ধান্তটি আবার "সবকিছু মুছে ফেলা"-তে ফিরে যেতে পারে না, কারণ তাহলে একটি টেস্ট ব্যর্থ হবে।
সমস্যা ২: ডিপ্লয় টুল উল্টে দেওয়ার উপায় লিখে রাখার আগেই ব্যর্থ হতে পারত
এই সংশোধনের পরপরই আমরা এতে একটি ফাঁক পেলাম। হোস্টিং প্ল্যাটফর্মের ডিপ্লয় টুল নিজের স্মোক চেক চালায়: নতুন মেশিন ক্র্যাশ করলে সে একটি ত্রুটি দিয়ে বেরিয়ে আসে। কিন্তু সেটি করে নতুন ইমেজ মেশিনে পৌঁছে যাওয়ার পরে।
আমাদের কোড কোনো অ্যাপকে রোলব্যাকের তালিকায় যুক্ত করত শুধু তখনই, যখন টুলটি সফলভাবে ফিরে আসত। টুলটি নিজে ডিপ্লয়কে ব্যর্থ করলে, অ্যাপটি তখনও তালিকায় ছিল না, তাই কিছুই ফেরানো হতো না। আমাদের স্টেজিং পরিবেশে একটি ভাঙা পুনঃপ্রকাশের পর ভাঙা ইমেজটিই চালু থেকে গিয়েছিল।
সমাধান: শুরুর আগেই উল্টে দেওয়ার উপায় নিবন্ধন করুন
এখন কোনো অ্যাপ প্রস্তুত হওয়া মাত্র, এবং তার ওপর কিছু ছড়ানোর আগে, রোলব্যাকের জন্য নিবন্ধিত হয়। সঙ্গে থাকে সেটি তৈরি হয়েছিল কি না এবং আগের ইমেজ কী ছিল। এরপর যা-ই ব্যর্থ হোক, রোলব্যাক জানে কী ফেরাতে হবে। আমরা স্থানীয়ভাবে যাচাই করেছি: একটি ভাঙা পুনঃপ্রকাশ ডিপ্লয় টুলের নিজের স্মোক চেকেই ব্যর্থ হয়েছে, এবং আগের সংস্করণটিই সাড়া দিতে থেকেছে।
সমস্যা ৩: একটি ঘুমন্ত অ্যাপকে "কখনো শুরু হয়নি" বলে ব্যর্থ ধরা হলো
Mythex-এ প্রকাশিত অ্যাপগুলো নিষ্ক্রিয় থাকলে ক্রেডিট বাঁচাতে ঘুমিয়ে পড়ে। পুনঃপ্রকাশ একটি বন্ধ মেশিনকে বন্ধ অবস্থায় রেখে দেয়, তাই হেলথ চেককে সেটি জাগাতে হয়। আগে সেটি প্ল্যাটফর্মকে মেশিনটি শুরু করতে বলত একবার, এবং উত্তরটি উপেক্ষা করত।
২৫ সেপ্টেম্বর সেই একটি শুরুর অনুরোধ কোথাও পৌঁছায়নি। একটি সুস্থ API পুরো পাঁচ মিনিটের হেলথ চেক জুড়ে বন্ধ পড়ে ছিল এবং "১টি মেশিন কখনো শুরু হয়নি (শেষ অবস্থা: বন্ধ)" বলে ব্যর্থ ঘোষিত হয়।
প্ল্যাটফর্ম কখনো কখনো শুরু করতে অস্বীকার করে। এটি পুনরুৎপাদনের সময়, আমরা উসকানি না দিলেও, একটি "lease currently held" সংঘাত ফিরিয়েছিল, এবং মেশিন আপডেট চলাকালে শুরুর অনুরোধ প্রত্যাখ্যান করে।
সমাধান: বারবার চাওয়া, এবং দরজায় কড়া নাড়া
হেলথ চেক এখন:
- অপেক্ষার সময় প্রতি ২০ সেকেন্ডে বন্ধ মেশিনটি আবার শুরু করতে বলে,
- প্রত্যাখ্যান করলে প্ল্যাটফর্ম কী উত্তর দিয়েছে তা লগ করে, এবং
- অ্যাপে একটি সাধারণ অনুরোধ পাঠায়, যেমনটা একজন দর্শক করতেন। প্ল্যাটফর্মের প্রক্সি অনুরোধ এলে একটি ঘুমন্ত মেশিনকে জাগিয়ে তোলে।
আমরা বাস্তব প্ল্যাটফর্মে একটি ডিসপোজেবল অ্যাপ দিয়ে এটি পুনরুৎপাদন করেছি, যার প্রথম শুরুর চেষ্টা প্রত্যাখ্যান করা হয়েছিল। সংশোধনের আগে প্রকাশ ৯১ সেকেন্ড পরে ব্যর্থ হতো। পরে সেটি ২০ সেকেন্ডে প্রকাশ হয়েছে। যে অ্যাপ সত্যিই বুট করার সময় ক্র্যাশ করে, সেটি এখনও ব্যর্থ হয়, যেমন হওয়া উচিত।
আমরা যা শিখেছি
- রোলব্যাককে নতুন আর বিদ্যমানের পার্থক্য জানতে হবে। যা আপনি তৈরি করেছেন তার "উল্টে দেওয়া" মানে মোছা। যা আগে থেকেই ছিল তার "উল্টে দেওয়া" মানে ফিরিয়ে আনা। দুটিকে একই ধরলে একটি নিরাপত্তা-ব্যবস্থাই একটি কাজ-করা অ্যাপ মুছে ফেলে।
- কাজ শুরুর আগে লিখে রাখুন কীভাবে উল্টাতে হবে। যদি উল্টে দেওয়ার উপায় শুধু একটি ধাপ সফল হওয়ার পরে লেখা হয়, তাহলে মাঝপথে ব্যর্থ ধাপটি উল্টানোর কিছু পায় না।
- যে অনুরোধের ওপর নির্ভর করেন, তার উত্তর কখনো উপেক্ষা করবেন না। একটি উপেক্ষিত "না" একটি সুস্থ অ্যাপকে ব্যর্থ প্রকাশে পরিণত করেছিল।
এই দিনেরই একটি সম্পর্কিত সংশোধন: প্রকাশের ঠিক পরে ক্র্যাশ করা অ্যাপ ধরা। আপনার দিক থেকে প্রকাশ ব্যর্থ হলে কী করণীয়, তার জন্য ডকসের প্রকাশের সমস্যা সমাধান দেখুন।