2011-01-24 27 views
9

मैं एक सामान्य मॉड्यूल लिखना चाहता हूं जो हास्केल प्रोग्राम को कैसंड्रा से बातचीत करने की अनुमति देता है। मॉड्यूल को अपने राज्य को बनाए रखने की आवश्यकता होगी। उदाहरण के लिए, इसमें एक कनेक्शन पूल होगा और एक नया रिकॉर्ड सहेजा जाने पर कॉलबैक की एक सूची होगी। मुझे कोड को कैसे ढूढ़ना चाहिए ताकि यह मॉड्यूल अपना राज्य बनाए रख सके? यहां कुछ ऐसे दृष्टिकोण दिए गए हैं जिन पर मैं विचार कर रहा हूं। क्या मैं सही रास्ते पर हूं? (मैं हास्केल के लिए नया हूँ और अभी भी बेहतरीन तरीके सीखने कार्यात्मक रूप में सोचने के लिए।)आप हास्केल में एक राज्यव्यापी मॉड्यूल कैसे बनाते हैं?

विकल्प 1:

मॉड्यूल एक (StateT रों आईओ) इकाई, जहां संपूर्ण के लिए वैश्विक स्थिति है में चलाता है कैसंड्रा मॉड्यूल का उपयोग कर कार्यक्रम। बेशक, चूंकि कैसंड्रा मॉड्यूल का उपयोग कई कार्यक्रमों द्वारा किया जा सकता है, इसलिए कैसंड्रा मॉड्यूल में क्या है इसका विवरण अदृश्य होना चाहिए। मॉड्यूल को एक प्रकार की कक्षा को निर्यात करना होगा जिसने इसे कैसंड्रास्टेट को निकालने की अनुमति दी है और एक नया कैसंड्रास्टेट वापस एस में धक्का दिया है। फिर, मॉड्यूल का उपयोग करने वाले किसी भी कार्यक्रम को अपने मुख्य राज्य को इस प्रकार के वर्ग का सदस्य बनाना होगा।

विकल्प 2:

मॉड्यूल एक (StateT CassandraState आईओ) इकाई में चलता है। हर बार जब कोई मॉड्यूल में कोई कार्रवाई करता है, तो उन्हें जहां भी इसे बंद कर दिया जाता है, वहां से कैसंड्रास्टेट निकालना होगा, रनस्टेट के साथ कार्रवाई का आह्वान करना होगा, और परिणामस्वरूप राज्य लेना होगा और इसे फिर से (कहीं भी) बंद कर देना होगा।

विकल्प 3:

बिल्कुल एक StateT इकाई में कैसेंड्रा मॉड्यूल के कार्यों न रखें। इसके बजाए, जब आवश्यक हो तो कॉलर स्पष्ट रूप से कैसंड्रास्टेट में पास हो जाए। विकल्प 2 के साथ समस्या यह है कि मॉड्यूल में सभी कार्य राज्य को संशोधित नहीं करेंगे। उदाहरण के लिए, कनेक्शन प्राप्त करने से राज्य को संशोधित किया जाएगा और परिणामस्वरूप राज्य को छेड़छाड़ करने के लिए कॉलर की आवश्यकता होगी। लेकिन, एक नया रिकॉर्ड सहेजने के लिए राज्य को पढ़ने की जरूरत है (कॉलबैक प्राप्त करने के लिए), लेकिन इसे राज्य को बदलने की जरूरत नहीं है। विकल्प 2 कॉलर को कोई संकेत नहीं देता है जो बनाते समय राज्य को बदलता है।

लेकिन, अगर मैं स्टेटटी मोनैड का उपयोग करने से दूर हो जाता हूं और केवल ऐसे कार्य होते हैं जो राज्यों में पैरामीटर के रूप में लेते हैं और सरल मूल्यों या नए राज्यों के सरल मूल्य या टुपल लौटते हैं, तो कॉलर के लिए वास्तव में स्पष्ट है जब राज्य की जरूरत है बचाया जा सकता है। (मेरे मॉड्यूल में कवर के तहत, मैं आने वाले राज्यों को ले जाऊंगा और उन्हें एक (स्टेटटी कैसंड्रास्टेट आईओ) मोनड में बनाउंगा, लेकिन इसका विवरण कॉलर से छिपा होगा। इसलिए, कॉलर को, इंटरफ़ेस बहुत स्पष्ट है बाकी

कुछ:, लेकिन कवर के तहत, यह सिर्फ विकल्प 2.)

विकल्प 4 है?

पुन: प्रयोज्य मॉड्यूल बनाने के दौरान यह समस्या अक्सर बार-बार आनी चाहिए। क्या इसे हल करने के लिए कोई मानक तरीका है?

(वैसे, अगर किसी को बचत का उपयोग करने से हास्केल से कैसेंड्रा के साथ बातचीत करने का एक बेहतर तरीका जानता है, मुझे पता है! हो सकता है कि मैं इस बारे में की जरूरत नहीं है तो कृपया। :-)

+2

एफवाईआई - हास्केल सर्कल 'मॉड्यूल' में संकलन की इकाई है, यानी - एक एकल स्रोत फ़ाइल है। यद्यपि मेरे पास वर्णन करने के लिए वास्तव में एक बेहतर संज्ञा नहीं है, लेकिन 'मॉड्यूल' के बारे में बोलने से राज्य ने मुझे एक पल के लिए फेंक दिया। –

+0

ओह। मुझे 'पैकेज' या 'लाइब्रेरी' कहा जाना चाहिए था। –

उत्तर

9

एचडीबीसी मॉडल की तरह कुछ स्पष्ट CassandraConnection डेटा प्रकार होना चाहिए। इसमें कुछ परिवर्तनीय राज्य के साथ एक एमवीआर है। चूंकि आपके सभी कार्य IO में हैं, वैसे भी मैं कल्पना करता हूं, वे केवल इन कार्यों के लिए एक तर्क के रूप में CassandraConnection ले सकते हैं। उपयोगकर्ता तब उस कनेक्शन को किसी राज्य या पाठक मोनैड में पैक कर सकता है, या इसे स्पष्ट रूप से थ्रेड कर सकता है, या जो चाहें वह कर सकता है।

आंतरिक रूप से आप एक मोनैड का उपयोग कर सकते हैं या नहीं - यह वास्तव में आपका कॉल है। हालांकि, मैं एपीआई का पक्ष लेता हूं कि जब संभव हो तो उपयोगकर्ताओं को किसी भी विशेष मोनैड में वास्तव में जरूरी नहीं है जब तक कि वास्तव में आवश्यक न हो।

तो यह विकल्प 3 का एक प्रकार का संस्करण है। लेकिन उपयोगकर्ता को वास्तव में परवाह नहीं करना चाहिए कि वे कनेक्शन स्थिति बदल रहे हैं या नहीं - उस स्तर पर आप वास्तव में उनसे ब्योरा छिपा सकते हैं।

+0

मुझे यह अन्य प्रश्न मिला है जो एमवीआर के उपयोग से एचडीबीसी कनेक्शन को पूल करने के बारे में बात कर रहा है। मुझे लगता है कि यह बता रहा है कि आप क्या सुझाव दे रहे हैं। http://stackoverflow.com/questions/1141677/concurrent-db-connection-pool-in-haskell –

+0

यदि अतिरिक्त रूप से, आप अपने सभी कार्यों के प्रकारों को ढूढ़ते हैं ताकि वे '... -> कैसंड्राकनेक्शन -> IO में समाप्त हो जाएं ए', आपके उपयोगकर्ता भी 'रीडर टी' मोनैड ट्रांसफार्मर के माध्यम से विकल्प 2 में समान रूप से समान अमूर्तता प्राप्त कर सकते हैं। वे आसानी से 'रीडर टी' कन्स्ट्रक्टर में पुस्तकालय कार्यों को लपेट सकते हैं। ईजी, 'foo :: ए -> बी -> कैसंड्राकनेक्शन -> आईओ सी' के रूप में लपेटा गया है: 'myFoo a b = ReaderT (foo a b) '। – mokus

+0

@Clint ऐसा लगता है। आप मूल रूप से संसाधनों के लिए एक सार संभाल चाहते हैं, स्पष्ट संचालन कनेक्ट करने, डिस्कनेक्ट इत्यादि के साथ – sclv

3

मैं विकल्प 2 के साथ जाएं। आपके मॉड्यूल के उपयोगकर्ताओं को runState का उपयोग सीधे नहीं करना चाहिए; इसके बजाय, आपको Monad टाइपक्लास के उदाहरण के साथ एक अपारदर्शी Cassandra प्रकार प्रदान करना चाहिए और कुछ runCassandra :: Cassandra a -> IO a कैसंड्रा से बचने के लिए ऑपरेशन करना चाहिए। आपके मॉड्यूल द्वारा निर्यात किए गए संचालन सभी को Cassandra मोनड (उदा। doSomethingInterestingInCassandra :: Int -> Bool -> Cassandra Char) में चलाया जाना चाहिए, और उनकी परिभाषा लिपटे CassandraState तक पहुंच सकती है।

यदि आपके उपयोगकर्ताओं को उनके आवेदन के लिए कुछ अतिरिक्त राज्य की आवश्यकता है, तो वे हमेशा Cassandra के आसपास एक मोनाड ट्रांसफॉर्मर को लपेट सकते हैं, उदा। StateT MyState Cassandra

+2

उत्तर के लिए धन्यवाद। मान लीजिए कि एक एप्लिकेशन सिर्फ मेरे कैसंद्रा मॉड्यूल का उपयोग नहीं कर रहा है, बल्कि कई अन्य राज्य मॉड्यूल का भी उपयोग कर रहा है। मान लीजिए कि एप्लिकेशन को अपने राज्य (माइस्टेट) को परिभाषित करने और आईओ मोनड में चलाने की आवश्यकता है। क्या आप स्टेट टी के अंदर एम्बेडेड स्टेटटी के एक गंदे सेट के साथ खत्म हो जाते हैं, और इसमें से कुछ भी प्राप्त करने के लिए उठाने के ग़लत अनुक्रम? जब सड़क एक नए राज्यव्यापी मॉड्यूल का उपयोग शुरू करती है या एक राज्यव्यापी मॉड्यूल का उपयोग बंद हो जाती है तो सड़क के नीचे क्या होता है? क्या यह सभी नेस्टेड स्टेटटी और उठाने को गड़बड़ कर देता है? –

संबंधित मुद्दे