2011-03-27 6 views
5

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

Factory(protocol.ReconnectingClientFactory): 

    def clientConnectionFailed(self, connector, reason): 
     ... 

    def clientConnectionLost(self, connector, reason): 
     ... 

मुझे लगता है कि अगर मैं शीर्ष स्तर स्क्रिप्ट (स्क्रिप्ट कि मॉड्यूल का आयात करता है) को सूचित यह सबसे अच्छा है जब वहाँ कनेक्शन समस्याओं कर रहे हैं:

यहाँ मैं क्या है की एक संक्षिप्त उदाहरण है। इस प्रकार शीर्ष स्तरीय स्क्रिप्ट मॉड्यूल में हार्ड कोड किए जाने के बजाय डिस्कनेक्ट रिज़ॉल्यूशन व्यवहार को परिभाषित कर सकती है। लेकिन शीर्ष स्तर की स्क्रिप्ट में कनेक्शन समस्याओं को संवाद करने का सबसे अच्छा तरीका क्या है?

मैं अपवाद उठा सकता हूं, लेकिन इसे पकड़ा जाएगा? मुझे लगता है कि रिएक्टर इसे पकड़ लेगा, लेकिन यह कैसे मदद करता है?

कनेक्शन समस्या की शीर्ष स्क्रिप्ट को सूचित करने के लिए कोई कॉलबैक या त्रुटियां नहीं हैं जिन्हें मैं आग लगा सकता हूं।

शीर्ष स्क्रिप्ट कनेक्शन समस्याओं के दौरान विशिष्ट कार्यों [तर्क के रूप में] कहलाया जा सकता है। हालांकि यह अच्छा डिजाइन है?

उत्तर

3

यह प्रश्न प्रत्यक्ष उत्तर प्रदान करने के लिए थोड़ा सा सार है। यह इस बात पर निर्भर करता है कि आपका शीर्ष-स्तर मॉड्यूल क्या कर रहा है।

हालांकि, आपको ClientFactory के बजाय endpoints का उपयोग करने पर विचार करना चाहिए। यह आपके कुछ डिज़ाइन प्रश्नों को संबोधित कर सकता है। कनेक्शन खोने वाली अधिसूचनाएं प्राप्त करना एक छोटा सा चालक है (ClientFactory.clientConnectionLost वास्तव में IProtocol.connectionLost की डुप्लिकेट अधिसूचना है, यह अब एंडपॉइंट्स एपीआई में मौजूद नहीं है, इसलिए आपको IProtocol ऑब्जेक्ट को लपेटना होगा यदि आप इसकी परवाह करते हैं) लेकिन यह आपको अधिक जेनेरिक का उपयोग करने देता है को पुनः प्रयास करने के लिए तंत्र कनेक्शन विफल रहे, clientConnectionFailed के बजाय, आपको बस Deferred पर एक त्रुटि मिल गई है जिसे आप connect से वापस प्राप्त कर चुके हैं। इसी तरह

# Warning, untested, sorry if it's broken. 
@inlineCallbacks 
def retry(deferredThing, delay=30.0, retryCount=5): 
    retries = retryCount 
    while True: 
     try: 
      result = yield deferredThing() 
     except: 
      if not retries: 
       raise 
      retries -= 1 
      log.err() 
      yield deferLater(reactor, delay, lambda : None) 
     else: 
      returnValue(result) 

, अगर: तो, उदाहरण के लिए, तुम सब किया गया था "पुन: कनेक्ट रखने के लिए जब तक आप सफल" करना चाहता था, तो आप इस पूरी तरह से सामान्य Deferred -retry लूप बजाय कनेक्शन के लिए विशिष्ट कुछ के ReconnectingClientFactory की तरह इस्तेमाल कर सकते हैं, तो आप deferredThing फ़ंक्शन को Deferred वापस कर सकते हैं जो केवल IStreamServerEndpoint.connect पर कॉल करने के अलावा पर कॉल करने के अलावा, आपके प्रोटोकॉल के एप्लिकेशन तर्क को पूरा करने के दौरान ही आग लग जाएगा, और रोचक तर्क पूरा होने से पहले कनेक्शन खो गया था तो विफल हो जाएगा।

Deferreds सिस्टम के कई स्तरों पर इस तरह के एसिंक्रोनस पुन: प्रयास राज्य को प्रबंधित करने का एक प्रभावी तरीका हो सकता है।

+1

यह एक अपूर्ण समाधान प्रतीत होता है, क्योंकि यह केवल असफल कनेक्शन प्रयासों को संभालने का तरीका देता है, कनेक्शन खो नहीं जाता है। प्रोटोकॉल से सहयोग के बिना आप खोए गए कनेक्शन कैसे प्रबंधित करते हैं? –

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

  • कोई संबंधित समस्या नहीं^_^