वर्षों तक फॉर्म भरने और इंतज़ार करने के बाद, आपको अपना बैंकिंग लाइसेंस मिल ही गया। इसका मतलब है कि अब आप आधिकारिक रूप से अपना बैंक खोल सकते हैं, वाह!
आपकी पहली प्राथमिकता आईटी सिस्टम को काम करने लायक बनाना है। एक दिन की मेहनत के बाद, आप अब खाते खोल और बंद कर सकते हैं, और निकासी तथा जमा भी संभाल सकते हैं।
चूँकि आप टेस्ट लिखने की मेहनत नहीं करना चाहते थे, आप कुछ दोस्तों को सिस्टम परखने में मदद के लिए बुलाते हैं। लेकिन सिर्फ पाँच मिनट बाद, आपके एक दोस्त का दावा है कि उसका पैसा गायब हो गया है! हालाँकि आपको पूरा भरोसा है कि आपके कोड में कोई बग नहीं है, फिर भी आप जाँच करने के लिए लॉग देखने लगते हैं।
आह, हाँ, जैसा आपको संदेह था, गलती आपके दोस्त की ही है! उसने अपने टेस्ट क्रेडेंशियल किसी और दोस्त के साथ साझा किए, और दोनों ने मिलकर एक ही खाते से समानांतर में जमा और निकासी करने की चाल चली। ऐसा भला कौन करेगा?
जब आप यह तर्क करते हैं कि किसी के लिए अपने खाते को समानांतर में एक्सेस करना भौतिक रूप से असंभव है, तो आपका दोस्त आत्मसंतुष्ट होकर आपको बताता है कि बैंकिंग नियम आपको इसे सपोर्ट करने के लिए बाध्य करते हैं। इसलिए, समानांतर बैंकिंग सपोर्ट नहीं, तो लाइव होने का संकेत भी नहीं। आह भरते हुए, आप मन में लिख लेते हैं कि कल इस पर काम करना है। इससे आपकी लॉन्च तारीख कम से कम एक दिन और पीछे चली जाएगी, लेकिन जो भी हो...
आपको ऐसे बैंक खाते बनाने हैं जिन्हें खोला और बंद किया जा सके, और जिनमें पैसा जमा किया जा सके तथा निकाला जा सके।
बैंक खातों तक कई अलग-अलग तरीकों से पहुँचा जा सकता है (इंटरनेट, मोबाइल फोन, ऑटोमैटिक चार्ज), इसलिए आपके बैंक सॉफ्टवेयर को यह सुविधा देनी चाहिए कि एक ही समय में कई थ्रेड या प्रोसेस (यह शब्द आपकी प्रोग्रामिंग भाषा पर निर्भर करता है) खातों तक सुरक्षित रूप से पहुँच सकें। उदाहरण के लिए, एक साथ बहुत सारी जमा और निकासी हो सकती हैं; आपको यह सुनिश्चित करना है कि खाते का बैलेंस पढ़ने और नया बैलेंस सेट करने के बीच कोई रेस कंडीशन न हो।
खाता बंद करना भी संभव होना चाहिए। बंद खाते पर की जाने वाली हर कार्रवाई विफल होनी चाहिए।
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 लीजिए और आठ क्लाइंट से 100 जमा भेजिए:
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) से बड़े अपडेट अस्वीकार कर देता है।
समानांतर में स्वतंत्र गणनाएँ चलाने का उदाहरण देखने के लिए parallel-letter-frequency अभ्यास आज़माइए।
Closed और Open(balance) में फर्क करने के लिए match इस्तेमाल कीजिए।
कोई ऑपरेशन उसे दिए गए खाते को बदलता नहीं, बल्कि अपडेट किया गया खाता लौटाता है।
सफल अपडेट के लिए Ok(updated_account) और अस्वीकृत ऑपरेशन के लिए Err(...) इस्तेमाल कीजिए।
Exercism पर साइन अप कीजिए और Roc को 135 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।