কম্পিউটার টিউটোরিয়াল

রেইলস অ্যাপ্লিকেশন স্ট্রিমলাইন: গ্লোবাল কনটেক্সটের জন্য কম্প্যাক্ট ActiveSupport মডিউল

সাধারণত, গ্লোবাল ভেরিয়েবল খারাপ। কিন্তু কখনো কখনো, সঠিক জায়গায় একটি গ্লোবাল আপনার কোডকে অনেক সিম্পল बना দিতে পারে।

রেইলসে, আপনি একবার রিকোয়েস্টের সময় ডেটা সেট করতে পারেন, কিন্তু অ্যাপ্লিকেশনের প্রতিটি লেয়ারে সেটা ব্যবহার করতে পারেন। কী ইউজার রিকোয়েস্ট করছে? তাদের পারমিশন কী? কোন ডাটাবেস কানেকশন ব্যবহার করা উচিত?

এই ইনফরমেশন আপনার কোড 전반ে উপলব্ধ থাকা উচিত, তাই সেটা সব জায়গায় পাস করা শুধু শোর হবে। কিন্তু রুবি গ্লোবাল ভেরিয়েবল ব্যবহার করা, বা ক্লাস ভেরিয়েবল সেট করা, নিজস্ব সমস্যা সৃষ্টি করবে। মাল্টিপল থ্রেড সেটাকে ওভাররাইট করতে পারে, এবং আপনি একটি বিশাল গুলগুলি এবং হয়তো অনরিকভারেবল ব্যাড ডেটায় ফিনিশ করবেন।

আপনার দরকার এমন কিছু যা গ্লোবাল, কিন্তু শুধু আপনার রিকোয়েস্টের জন্য।

সাদা রুবি পদ্ধতি

সাধারণত, এটা Thread.current[] দিয়ে হ্যান্ডল করা হয়। এটা এমন দেখায়:

Thread.current[:current_user] = user

এটা পর্যাপ্ত সিম্পল। এটা একটি ডিসেন্ট সমাধান। কিন্তু এর দুটি বড় ড্রব্যাক আছে:

  1. কেউ অজান্তে আপনার ডেটা ওভাররাইট করতে পারে।

    দুজন যদি একই কী বেছে নেয়? আপনি একে অপরের ডেটায় পা দিবেন। এবং আপনি যদি ইউজার স্টোর করেন, তবে সেটা খুব খারাপ হবে। আপনার নিজের অ্যাপ্লিকেশনে এটা সমস্যা হয় না। কিন্তু আপনি যদি জেম লিখেন, অথবা আপনার রেইলস অ্যাপ্লিকেশন বড় ও গুলগুলি হয়, তবে এটা চিন্তা করতে হবে।

  2. এটা ভালো স্ট্রাকচার্ড নয়।

    Thread.current[] শুধু একটি বড় ডেটা ব্যাগ। আপনি সহজে সেটাকে ডকুমেন্ট করতে পারবেন না। আপনি যদি জানতে চান সেখান থেকে কী বের করতে পারেন, তবে আপনাকে সেটা খুঁজতে হবে যা আপনি দিয়েছেন।

    ব অবশ্য, আপনি যদি এতটুকু গ্লোবাল ডেটা রাখেন যে এটা সমস্যা হয়, তবে আপনার চিন্তার বিষয় Thread.current[]-এর স্ট্রাকচার না থাকা নয়। তবুও এটা মনে রাখার একটি পয়েন্ট।

তো, Thread.current[]-এর চেয়ে ভালো সমাধান আছে কি? আপনি কল্পনা করতে পারেন, রেইলস নিজে অনেক রিকোয়েস্ট-লোকাল ডেটা ম্যানেজ করে। এবং ActiveSupport-এর গুডি বক্সে একটি আলাদা প্যাটার্ন আছে ফলো করার জন্য।

রেইলস পদ্ধতি

যদি আপনি ActiveSupport খনন করেন, তবে ActiveSupport::PerThreadRegistry পেতে পারেন। নাম থেকে বুঝা যায় এটি ঠিক আমরা যা খুঁজছি।

ActiveSupport::PerThreadRegistry দিয়ে, আগের উদাহরণটি এমন দেখাবে:

class RequestRegistry extend ActiveSupport::PerThreadRegistry attr_accessor :current_user, :current_permissions end RequestRegistry.current_user = user RequestRegistry.current_user # => user

এটা একটু বেশি কাজ। কিন্তু ActiveSupport::PerThreadRegistry দিয়ে:

  • আপনার पास ডকুমেন্টেশন রাখার জায়গা আছে। আপনার ক্লাস দেখলে কেউ বুঝতে পারবে আপনি কী গ্লোবাল ডেটা এক্সপেক্ট করছেন, এবং কী গ্লোবাল ডেটা ব্যবহার করতে পারেন।

  • আপনি একটি ভালো দেখার API পাবেন। ফ্যাক্ট, এটা যেন ক্লাস ভেরিয়েবল সেট করছেন। সেটা সম্ভবত আপনি করতেন যদি থ্রেডের চিন্তা করতে হতো না।

  • আপনি ক্লাসে সেট করা যেকোনো ডেটা নেমস্পেসড হবে। আপনাকে চিন্তা করতে হবে না RequestRegistry.current_user কে PhoneNumberApiRegistry.current_user দিয়ে কোলাইড করবে, সেগুলো পুরোপুরি আলাদা আলাদা ট্রিট হবে।

রেইলস ActiveSupport::PerThreadRegistry ইন্টারন্যালি ব্যবহার করে, এক্টিভরেকর্ড কানেকশন হ্যান্ডলিং, EXPLAIN কুয়েরি স্টোর করা, এবং ActiveSupport::Notifications-এর জন্য। তাই আপনি যদি PerThreadRegistry-র শক্তির আরও ভালো উদাহরণ খুঁজেন, রেইলস নিজেই একটি দুর্দান্ত জায়গা।

যখন থ্রেড এবং রিকোয়েস্ট মেলে না

কিছু রেইলস সার্ভারের জন্য, একটি থ্রেড একাধিক রিকোয়েস্ট হ্যান্ডেল করে। এর মানে PerThreadRegistry-এ আপনি যা রাখবেন সেটা পরবর্তী রিকোয়েস্টের জন্যও থাকবে। এটা সম্ভবত আপনি চান না।

আপনি রেইলস যা করে সেটা করতে পারেন, এবং PerThreadRegistry-এ আপনি যা রাখলেন সেগুলো শেষে ক্লিন আপ করুন। আপনি সেখানে কী রাখলেন তার ওপর নির্ভর করে, আপনি ইতিমধ্যে এটা করছেন।

কমেন্টে MattB request_store-কে পয়েন্ট করেছেন। এটা Thread.current[]-এর মত কাজ করে, কিন্তু প্রতিটি রিকোয়েস্টের পর নিজে ক্লিয়ার হয়।

এটি দরওয়াজা খুলে দিয়েছে PerRequestRegistry তৈরি করার জন্য, যা request_store-এর সেফটি এবং PerThreadRegistry-এর API কম্বাইন করবে। কেউ যদি এটা ইতিমধ্যে বানিয়ে থাকে, আমি জানতে চাই!

ট্রাই করুন

গ্লোবাল ডেটা খারাপ হতে পারে। খুব বেশি গ্লোবাল দ্রুত আনমেইনটেইনেবল কোডে নিয়ে যেতে পারে।

তবে যদি একটি রিকোয়েস্টের জন্য ডেটা সেন্ট্রাল জায়গায় রাখা মানে রাখে, Thread.current[]-এর বাইরে যান। ActiveSupport::PerThreadRegistry বা request_store ট্রাই করুন। যদি অন্য কিছু না হয়, গ্লোবাল ডেটা হ্যান্ডল করা একটু কম রিস্কি হবে।

  1. ডেটা সেন্টার কী?

  2. OLAP কী?

  3. হ্যাকাররা কীভাবে কোম্প্রোমাইজড ওয়েবসাইট শোষা করে

  4. বিগ ডেটার সম্ভাব্য ঝুঁকি এবং আশুশমনের কৌশল: কী কী ভুল হতে পারে?