বছরের পর বছর ফর্ম পূরণ আর অপেক্ষা করার পর, অবশেষে আপনি আপনার ব্যাংকিং লাইসেন্স পেয়ে গেছেন। এর মানে হলো, এখন আপনি আনুষ্ঠানিকভাবে নিজের একটি ব্যাংক খোলার যোগ্যতা পেয়ে গেছেন, বাহ!
আপনার প্রথম কাজ হলো IT সিস্টেমগুলো চালু করা। একদিনের কঠোর পরিশ্রমের পর আপনি ইতিমধ্যেই অ্যাকাউন্ট খুলতে ও বন্ধ করতে পারছেন, আর উইথড্র ও ডিপোজিটও সামলাতে পারছেন।
টেস্ট লিখতে আপনার আলসেমি লাগছিল বলে, সিস্টেমটি টেস্ট করতে সাহায্যের জন্য আপনি কিছু বন্ধুকে ডেকে আনলেন। কিন্তু মাত্র পাঁচ মিনিটের মধ্যেই আপনার একজন বন্ধু দাবি করল যে তার টাকা হারিয়ে গেছে! আপনার কোডে কোনো বাগ নেই বলে আপনি নিশ্চিত, তবুও তদন্ত করতে আপনি লগগুলো দেখা শুরু করলেন।
আহা, ঠিক যেমনটা আপনি সন্দেহ করেছিলেন, দোষটা আপনার বন্ধুরই! সে তার টেস্ট ক্রেডেনশিয়াল আরেক বন্ধুর সাথে শেয়ার করেছিল, আর দুজনে মিলে ষড়যন্ত্র করে একই অ্যাকাউন্টে প্যারালালে ডিপোজিট ও উইথড্র করতে শুরু করেছিল। এমন কাজ কে-ই বা করে?
কারও পক্ষে প্যারালালে নিজের অ্যাকাউন্টে ঢোকা শারীরিকভাবে অসম্ভব বলে আপনি যখন তর্ক করছেন, তখনই আপনার বন্ধু আত্মতুষ্ট ভঙ্গিতে আপনাকে জানাল যে ব্যাংকের নিয়ম এটিকে সমর্থন করা আপনার জন্য বাধ্যতামূলক করে দিয়েছে। তাই প্যারালাল ব্যাংকিং সাপোর্ট নেই মানে গো-লাইভের সিগন্যালও নেই। দীর্ঘশ্বাস ফেলে আপনি মনে মনে টুকে নিলেন, কাল এটা নিয়ে কাজ করতে হবে। এতে আপনার লঞ্চের তারিখ অন্তত আরও একদিন পিছিয়ে যাবে, কিন্তু, যা হোক...
আপনার কাজ হলো এমন ব্যাংক অ্যাকাউন্ট তৈরি করা যেগুলোতে অ্যাকাউন্ট খোলা/বন্ধ করা, টাকা জমা এবং টাকা উত্তোলনের সুবিধা থাকবে।
যেহেতু ব্যাংক অ্যাকাউন্টে নানা রকমভাবে (ইন্টারনেট, মোবাইল ফোন, স্বয়ংক্রিয় চার্জ) ঢোকা যায়, তাই আপনার ব্যাংক সফটওয়্যারকে অবশ্যই একাধিক থ্রেড/প্রসেস থেকে (পরিভাষাটি আপনার প্রোগ্রামিং ভাষার উপর নির্ভর করে) সমান্তরালভাবে অ্যাকাউন্টে নিরাপদে ঢোকার সুবিধা দিতে হবে। উদাহরণস্বরূপ, একসাথে অনেক জমা ও উত্তোলন ঘটতে পারে; অ্যাকাউন্টের ব্যালেন্স পড়ার এবং নতুন ব্যালেন্স সেট করার মধ্যে যেন কোনো রেস কন্ডিশন না থাকে, তা আপনাকে নিশ্চিত করতে হবে।
একটি অ্যাকাউন্ট বন্ধ করা সম্ভব হওয়া উচিত; বন্ধ অ্যাকাউন্টে করা যেকোনো কাজ ব্যর্থ হতে হবে।
Roc কোডে আমরা সাধারণত বিজনেস লজিক নিয়ে কাজ করি, আর প্ল্যাটফর্ম কনকারেন্সি ও শেয়ার্ড স্টেট সামলায়। তাই এই অনুশীলনীতে আপনাকে শুধু BankAccount.roc-এ অ্যাকাউন্টের অপারেশনগুলো ইমপ্লিমেন্ট করতে হবে; কনকারেন্সি নিয়ে ভাবতে হবে না। অ্যাকাউন্টগুলো শুরুতে বন্ধ থাকে, আবার খুললে ব্যালেন্স রিসেট হয়, আর ডিপোজিট ও উইথড্রয়াল অবশ্যই পজিটিভ হতে হবে।
সঙ্গে দেওয়া bank-account-demo.roc দেখায় কীভাবে আপনার ইমপ্লিমেন্টেশন একটি ছোট ওয়েব সার্ভিসে ব্যবহার করা যায়। আপনি এটি এডিটরে পড়তে পারেন, তবে এটি টেস্ট থেকে স্বাধীন এবং আপনার সমাধানের অংশ নয়।
ডেমোটি রান করতে হলে আপনাকে আপনার মেশিনে Roc ইনস্টল করতে হবে, Exercism CLI ইনস্টল করতে হবে, তারপর টার্মিনালে এই কমান্ডটি রান করতে হবে:
exercism download --exercise=bank-account --track=roc
এরপর BankAccount.roc ইমপ্লিমেন্ট করুন এবং নিচের কমান্ড দিয়ে এটি টেস্ট করুন (CLI যে ডাউনলোড লোকেশন প্রিন্ট করে সেটি নিচের পাথ থেকে ভিন্ন হলে সেটি পরিবর্তন করুন):
cd ~/Exercism/roc/bank-account
roc test bank-account-test.roc
সব টেস্ট পাস হলে নিচের কমান্ড দিয়ে ডেমো সার্ভারটি চালু করতে পারেন:
roc bank-account-demo.roc
সার্ভারটি basic-webserver প্ল্যাটফর্ম এবং এর বিল্ট-ইন SQLite সাপোর্ট ব্যবহার করে (প্রথমবার রান করার সময় Roc প্ল্যাটফর্মটি ডাউনলোড করে)। আলাদা কোনো ডাটাবেস সার্ভার প্রয়োজন নেই। সার্ভারটি http://127.0.0.1:8000-এ লিসেন করে এবং আপনার বর্তমান ডিরেক্টরিতে bank-account-demo.db তৈরি করে (ভিন্ন ডাটাবেস ফাইল ব্যবহার করতে DB_PATH সেট করুন)। Ctrl-C দিয়ে সার্ভারটি বন্ধ করুন। ডেটা রিস্টার্টের পরেও টিকে থাকে।
অন্য একটি টার্মিনালে আপনি curl দিয়ে ওয়েব সার্ভিসটি কল করতে পারেন (Windows-এ PowerShell-এর curl অ্যালিয়াস এড়াতে সব জায়গায় curl.exe ব্যবহার করুন)। উদাহরণস্বরূপ, #123 অ্যাকাউন্ট খুলতে, 50 ডিপোজিট করতে, 10 উইথড্র করতে এবং এর ব্যালেন্স দেখতে হলে ঠিক এভাবে করুন:
curl -X POST http://127.0.0.1:8000/accounts/123/open
curl -X POST http://127.0.0.1:8000/accounts/123/deposit/50
curl -X POST http://127.0.0.1:8000/accounts/123/withdraw/10
curl http://127.0.0.1:8000/accounts/123/balance
ব্যালেন্স হয় 40। অ্যাকাউন্ট ID এবং অ্যামাউন্ট অবশ্যই আনসাইন্ড ইন্টিজার হতে হবে। আপডেটগুলো সফল হলে OK এবং ব্যর্থ হলে আপনার অ্যাকাউন্ট ইমপ্লিমেন্টেশন থেকে একটি এরর রিটার্ন করে। #123 অ্যাকাউন্ট বন্ধ করতে:
curl -X POST http://127.0.0.1:8000/accounts/123/close
Linux/macOS-এ কনকারেন্ট রিকোয়েস্ট চেষ্টা করতে, একটি নতুন অ্যাকাউন্ট ID ব্যবহার করুন এবং আটটি ক্লায়েন্ট থেকে ১০০টি ডিপোজিট পাঠান:
curl -X POST http://127.0.0.1:8000/accounts/456/open
seq 100 | xargs -P 8 -I '{}' curl --fail --silent --show-error -X POST http://127.0.0.1:8000/accounts/456/deposit/1
curl http://127.0.0.1:8000/accounts/456/balance
Windows-এ প্যারালেল উদাহরণের জন্য PowerShell 7+ ব্যবহার করুন:
curl.exe -X POST http://127.0.0.1:8000/accounts/456/open
1..100 | ForEach-Object -Parallel { curl.exe --fail --silent --show-error -X POST http://127.0.0.1:8000/accounts/456/deposit/1 } -ThrottleLimit 8
curl.exe http://127.0.0.1:8000/accounts/456/balance
সব ডিপোজিটই সফল হওয়া উচিত এবং ব্যালেন্স হওয়া উচিত 100।
প্রতিটি রিকোয়েস্ট অ্যাকাউন্টটি পড়ে, আপনার Roc ফাংশনগুলো কল করে এবং একটি SQLite Immediate ট্রানজেকশনের মধ্যে ফলাফলটি সেভ করে। ব্যর্থ অপারেশনগুলো অ্যাকাউন্ট না বদলেই রোলব্যাক হয়। SQLite একসাথে একজন রাইটারকেই অনুমতি দেয়, ফলে কনকারেন্ট রিকোয়েস্টগুলো একে অপরের আপডেট ওভাররাইট করতে পারে না (এমনকি ভিন্ন অ্যাকাউন্টের ক্ষেত্রেও নয়)।
দ্রষ্টব্য: অনুশীলনীতে U64 ব্যবহার করা হয়, কিন্তু ডেমো ব্যালেন্সগুলো SQLite ইন্টিজার হিসেবে সংরক্ষণ করে এবং সর্বোচ্চ I64 মান (9223372036854775807) ছাড়িয়ে যাওয়া আপডেট প্রত্যাখ্যান করে।
সমান্তরালে স্বাধীন কম্পিউটেশন চালানোর উদাহরণের জন্য সমান্তরাল অক্ষর-কম্পাঙ্ক অনুশীলনী চেষ্টা করে দেখুন।
Closed থেকে Open(balance) আলাদা করতে match ব্যবহার করুন। একটি অপারেশন তার কাছে দেওয়া অ্যাকাউন্ট পরিবর্তন না করে একটি আপডেট হওয়া অ্যাকাউন্ট রিটার্ন করে। সফল আপডেটের জন্য Ok(updated_account) এবং প্রত্যাখ্যাত অপারেশনের জন্য Err(...) ব্যবহার করুন।
Exercism-এ সাইন আপ করুন, Roc ট্র্যাকের 135টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।