কয়েক দিন আগে আমি রিউইন্ড ভিএম সম্পর্কে লিখেছিলাম, একটি নির্ধারিত ভার্চুয়াল মেশিন যেখানে একটি নিক্স বিল্ডের প্রতিটি রান তার ইনপুটের একটি পরিষ্কার ফাংশন, থ্রেড সিডিউলিং অন্তরভুক্ত! আমি এটি নিক্স বিল্ডে রেস কন্ডিশন খুঁজে পাওয়া, পুনরুৎপাদন করা এবং সমাধান করার জন্য ব্যবহার করেছি, কিন্তু এটি আমকে একটু পাগল করে তুলেছে। এই কোন সুপারপাওয়ার, এবং অন্যারা কেন এটি ব্যবহার করছে না?
এই টুলটি দ্রুত একটি সোর্স প্যানেল, স্ট্যাক ফ্রেম, বুকমার্ক, একটি "কমপেয়ার" ট্যাব, অনেক জিডিবি সমর্থন, থ্রেড লেন যা দেখায় যে প্রতিটি স্টেপে কে সিপিইউ ধারণ করেছিল, এবং "চেক ফ্রম হের" যা রেস কন্ডিশন ঘটার ঠিক স্টেপটি খুঁজে পাওয়ে সহায়তা করে। আমি প্রতিটি নতুন ফিচারে প্রবেশ করেছিলাম ভাবতে যে এটি একটি বড় কোড উঠানামা হবে, কিন্তু আমি বারবার একই জিনিসের সাথে দেখা হয়েছিল: প্রতিটি ফিচারের কঠিন অংশই ইতিমধ্যে সম্পন্ন ছিল, এবং নিক্স এটি করেছিল।
উদাহরণ হিসাবে, একটি ডিবাগারের প্রয়োজন হয় প্রোগ্রামের সঠিক ইনপুট, এর ডিবাগ সিম্বলস, এর সোর্সস, তার নিচের প্রতিটি লাইব্রেরির সোর্সস, এবং একটি উপায় যে অন্য কেউ তাদের মেশিনে এই সব কিছু পেতে পারে। এটি ঠিক এমনই যেমন একটি ডেরিভেশন, এবং নিক্স এটিকে সহজ করে।
দুই তালাকার, একটি হিসাব
রেস কন্ডিশনের একটি ক্লাসিক সাধারণ উদাহরण হলো দুই থ্রেড একটি ব্যাংক অ্যাকাউন্টে ডিপোজিট করা। প্রতিটি ডিপোজিট ব্যালেন্স পড়ে, লেজারে একটি লাইন লেখে, তারপর ব্যালেন্স এবং ডিপোজিট স্টোর করে। যদি এক তালাকার অন্যের পড়া এবং স্টোরের মধ্যে চলে যায়, সে অন্যের ডিপোজিটের উপর একটি স্টেল ব্যালেন্স লেখে।
static void deposit(int teller, long amount){long seen = balance;char line[64];int n = snprintf(line, sizeof line,"teller %d: %ld + %ld\n",teller, seen, amount);if (write(1, line, n) != n)return;balance = seen + amount;}
এক তালাকার যা অন্যের পড়া এবং স্টোরের মধ্যে চলে যায়, অন্যের ডিপোজিটের উপর একটি স্টেল ব্যালেন্স লেখে।
11
আমার 16-কোর ল্যাপটপে, ব্যাংক ১,০০ৰ রানের মধ্যে ৩৯৬টিতে টাকা হারিয়েছে। টাস্কসেট দিয়ে একটি কোরে পিন করা হয়েছিল, ১,০০০টির একটিতেও টাকা হারায়নি: একটি কোর ডিপোজিটের মধ্যে থ্রেড পরিবর্তন করা খুব বিরল, তাই রিউইন্ড সিডিউলকে ব্যাঘিত করে।
রিউইন্ডের ভিএমে একটি সিপিইউ আছে, তাই তার প্রথম রান খুব ভালোভাবে হয়ে যায়। rewind check বিল্ডকে ব্যাঘিত সিডিউলের তहত আবার চালায়, প্রতিটি গেস্ট কার্নেলকে বিভিন্ন স্টেপে রিসিডিউল করার অনুরোধ করে, এবং প্রথম ফেলকে একটি স্টেপে সীমিত করে:
$ rewind check --where github:fzakaria/rewindvm#bank...step 3237 সিদ্ধান্ত: একটি রিসিডিউল রানকে ফেল করে
passing: run 12feb5f832205a72, schedule 0
failing: run c2f1cfac0c288f3e, schedule 1 over steps 3237..3238
দুইটি রান একই মেশিন, ইক্সিট ইক্সিট, স্টেপ 3237 পর্যন্ত, যেখানে কেবল ফেলিং একটি রিসিডিউল পায়।
ফ্রি জিনিস এক: ইনপুট
চেকের তর্ক হলো একটি ডেরিভেশন এবং এটি একটি ফ্লেক রেফারেন্স হতে পারে। নিক্সের সৌন্দর্য হলো এটি ডেরিভেশনের ইনপুট সম্পর্কে জানে, তাই এটিই আমাদের প্রয়োজন যে রান পুনরুৎপাদনীয় হয়। ডেরিভেশনের ইনপুট হলো সোর্স, কম্পাইলার, লাইব্রেরি, কার্নেল, এবং ভিএমের কনফিগারেশন। রিউইন্ড নিক্স ডেরিভেশনের ইনপুট বাস্তবায়ন করে, ক্লোজারকে একটি রিড-অনলি ইরোফস ইমেজে প্যাক করে, এবং ভিএমকে তার উপর বুট করে। রানের আইডি হলো তার ইনপুটের হ্যাশ, যেমন স্টোর পथের মতো, এবং রিউইন্ড শো প্রদর্শন করে কমান্ড যা এটি পুনরায় তৈরি করে:
$ rewind show 12feb5f8
rewind nix /nix/store/cr8rl40rjb9cmmcd9sxn9mpdrhvp53jj-bank-0.1.0.drv --epoch --clock branches --name bank-0.1.0 # 12feb5f832205a72
যখন বিল্ড সফল হয়, গেস্ট প্রতিটি আউটপুটের এনআর হ্যাশ রিপোর্ট করে, এবং রিউইন্ড নিক্স এটি হোস্টের সংস্করণ এবং নিক্স প্রতিস্থাপন করা বিভিন্ন বাইনারি ক্যাশের সাথে তুলনা করে, কেবল .narinfo ফেচ করে:
$ rewind nix github:fzakaria/rewindvm#bank.../nix/store/27a4q7w90jzp4wg5kaaajvb64zll6yqg-bank-0.1.0 dbf0df3de84b7a84 matches your store
এটি আমাদের সহায়তা করে যে ভিএমের মধ্যের বিল্ডটি আমার ল্যাপটপের বিল্ডের সমান, এবং ভিএমের রান নিক্স দ্বারা পুনরুৎপাদনীয়।
উৎস: Hacker News · সারাংশ: HeadlinesBriefing