2009-08-02 8 views
11

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

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

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

असीमित पाश में चलने वाले प्रोसेसिंग थ्रेड को अनदेखा करना भी स्वीकार्य नहीं था क्योंकि इसमें कुछ सीपीयू-गहन ऑपरेशन किए गए थे जो उपयोगकर्ता की मशीन को काफी धीमा कर देंगे।

एक और तरीका जिसकी मैंने कोशिश नहीं की थी, एक थ्रेड के बजाय अलग प्रक्रिया में प्रसंस्करण शुरू करना है, क्योंकि सॉफ़्टवेयर को असंगत स्थिति में डाले बिना एक उप-प्रक्रिया को साफ तरीके से मार दिया जा सकता है। या नया SwingWorker वर्ग (जो अभी तक उपलब्ध नहीं था) ने नौकरी की है? इसमें cancel() विधि है, लेकिन दस्तावेज़ों का कहना है कि यह "इस कार्य के निष्पादन को रद्द करने का प्रयास" है, इसलिए यह किसी विश्वसनीय दृष्टिकोण की तरह नहीं दिखता है।

उत्तर

11

मैं एक अलग प्रक्रिया के उपयोग की अनुशंसा करता हूं। जावा में दूसरे धागे को मारने के लिए एक थ्रेड के लिए अनिवार्य रूप से कोई सुरक्षित तरीका नहीं है जब तक कि दूसरा धागा समय-समय पर जांच न हो कि यह बाधित हो गया है या नहीं।

आदर्श समाधान अलग-अलग उपयोग करना होगा। एक पृथक अनिवार्य रूप से एक निजी आभासी मशीन है जो जावा ऐप बना, प्रबंधित और संचार कर सकती है। विशेष रूप से, अभिभावक ऐप सुरक्षित रूप से एक अलग और उसके सभी धागे को मार सकता है।

संदर्भ: JSR-000121 Application Isolation API Specification - Final Release

समस्या एक JVM आइसोलेट्स का समर्थन करता है कि जा रहे हैं।

+1

मैंने अलगाव API के दिलचस्प संदर्भ के कारण आपका उत्तर स्वीकार कर लिया। उसके लिए धन्यवाद! –

5

मैं इस तरह की चीज़ के लिए अलग प्रक्रियाओं का एक बड़ा प्रशंसक हूं।

एक उप प्रक्रिया स्पॉन करें और परिणामों की प्रतीक्षा करें।

यदि एपीआई गैर-निर्धारिती है, तो टाइमर थ्रेड को एक रैपर में डालें जो खराब एपीआई को मुख्य प्रोग्राम में बनाता है।

इस तरह, उपप्रोसेसर हमेशा दिए गए समय के भीतर समाप्त होता है। यह या तो एक उपयोगी परिणाम या सिस्टम निकास कोड उत्पन्न करता है जो विफलता को इंगित करता है।

+0

आपके उत्तर के लिए धन्यवाद, मुझे लगता है कि मैं उस दृष्टिकोण को आजमाउंगा। –

1

सर्वोत्तम काम करने के लिए एपीआई को फिर से कार्यान्वित करना होगा। हालांकि, जैसा कि आप कहते हैं, यह एक बहुत भारी वजन और संभवतः बाहर का दायरा समाधान है।

अगले सर्वोत्तम यदि संभव हो तो एपीआई को लपेटना होगा। असल में, यदि आप पहले से निर्धारित कर सकते हैं कि डेटासेट के बारे में क्या है जो विफलता का कारण बनता है तो कॉल को निर्धारित करने की गारंटी देने के लिए अस्वीकार कर सकता है। ऐसा लगता है कि यह आपके लिए भी काम नहीं करेगा, जैसा कि आप सुझाव देते हैं कि उसी डेटासेट के साथ कॉल दोहराए जाने पर कभी-कभी समाप्त हो जाएगा जब यह पहले से ही किसी पूर्व आमंत्रण में लूप हो गया था।

ऊपर ऊपर दिए गए विकल्पों को देखते हुए उपलब्ध नहीं हैं:
मुझे लगता है कि अपने वर्तमान धागा समाधानबुरा विकल्प का सबसे अच्छा है। एक विधि कॉल के लिए एक प्रक्रिया को कताई करना एक प्रदर्शन बिंदु-दृश्य से स्वीकार्य होने के लिए बहुत भारी वजन लगता है, भले ही यह धागे का उपयोग करने से सुरक्षित है। Thread.stop() बहुत खतरनाक है, लेकिन यदि आप धार्मिक रूप से किसी लॉकिंग को रोकते हैं तो आप इससे दूर हो सकते हैं।

+0

मैं यहां आपके साथ काफी सहमत नहीं हूं। एक समय में केवल एक उप-प्रक्रिया में ही होगा। इस सब-प्रोसेस के भीतर वास्तव में सीपीयू-गहन गणना होगी, इसलिए मुझे नहीं लगता कि एक और प्रक्रिया क्यों बनाना इतना बड़ा सौदा है। मुझे लगता है कि आप मान रहे हैं कि कई उप-प्रक्रियाएं होंगी, लेकिन मेरे कार्यक्रम को हमेशा केवल एक की आवश्यकता होगी। डेटा को पास करने और उसे पुनर्प्राप्त करने के लिए कुछ ओवरहेड होगा, हालांकि, लेकिन ऐसा करना मुश्किल नहीं होगा। खैर, वैसे भी आपके जवाब के लिए धन्यवाद। –

+0

मेरी चिंता __starting__ की प्रक्रिया के साथ है, किसी भी समय संख्या या लाइव प्रक्रिया नहीं। प्रक्रिया की लागत >> स्टार्टअप समय के मामले में धागे की लागत। मुझे लगता है कि आप इस एपीआई को बार-बार कॉल कर रहे हैं, जो मुझे लगता है कि प्रश्न को लिखा गया उचित है (हालांकि शायद यह आपकी वास्तविक स्थिति के बारे में सच नहीं है)। एपीआई गहन सीपीयू कैसे वास्तव में प्रासंगिक नहीं है, क्योंकि आप फिक्स के बावजूद उस लागत का भुगतान करते हैं। –

2

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

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

+0

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

+2

जब वास्तव में क्रैपी सॉफ्टवेयर सबसे अच्छा उपलब्ध होता है और लोग इसके लिए भुगतान करने को तैयार होते हैं, जिसे अवसर कहा जाता है। – tvanfosson