2014-11-17 4 views
6

में एलीक्सिर सुपरवाइजर को कैसे चलाएं मेरे पास एक सुपरवाइजर और जेनसेवर जितना आसान हो सके मिश्रण मिश्रण है। जब मैं आईईएक्स से फोन:एस्क्रिप्ट

EchoCmd.Supervisor.start_link([:Hello]) 
GenServer.call(:echoserver, :echo) 
GenServer.call(:echoserver, :mumble) 
GenServer.call(:echoserver, :echo) 

: बुदबुदाना कॉल एक अपवाद को जन्म देती है, तो GenServer पुन: प्रारंभ होने और दूसरा: कॉल ठीक काम करता है गूंज।

यदि मैं कोड को किसी अन्य तरीके से चलाता हूं तो सुपरवाइजर जेनसेवर को पुनरारंभ करने में विफल रहता है। उदाहरण के लिए, मैं इस प्रकार मुख्य मॉड्यूल के साथ परियोजना का एक escript बनाएँ:

defmodule EchoCmd.Echo do 
    def main(args) do 
     EchoCmd.Supervisor.start_link([:Hello]) 
     GenServer.call(:echoserver, :echo) 
     GenServer.call(:echoserver, :mumble) 
     GenServer.call(:echoserver, :echo) 
    end 
end 

: बुदबुदाना कॉल एक अपवाद को जन्म देती है और escript पर्यवेक्षक GenServer को पुन: प्रारंभ बिना समाप्त हो जाता है।

मैंने सुपरवाइजर और सर्वर मॉड्यूल कोड शामिल नहीं किया है क्योंकि वे आईईएक्स से कॉल करते समय ठीक काम करते हैं, इसलिए मुझे लगता है कि उन्हें यहां आवश्यकता नहीं है।

क्या मेरे पास एक वैचारिक गलतफहमी है? क्या यह संभव नहीं है, या मैं कुछ गलत कर रहा हूँ?

उत्तर

5

समस्या अपने सर्वर और पर्यवेक्षक में नहीं है, लेकिन रास्ते में आप उन्हें बुला रहे हैं यदि सर्वर बाहर निकलता है, जबकि दूसरी प्रक्रिया GenServer.call के उत्तर के लिए प्रतीक्षा कर रही है, तो कॉलिंग प्रक्रिया भी निकलती है, इसलिए अंतिम कॉल कभी नहीं होता है। इसका कारण यह है कि सिंक्रोनस कॉल विफल होने पर प्रक्रिया संभवतः अमान्य स्थिति में जारी नहीं हो सकती है (GenServer.callGenServer.cast के विपरीत सिंक्रोनस है)। आप यह सिर्फ पर्यवेक्षक परीक्षण करने के लिए कर रहे हैं, तो आप की कोशिश कर सकते हैं:

defmodule EchoCmd.Echo do 
    def main(args) do 
     EchoCmd.Supervisor.start_link([:Hello]) 
     GenServer.cast(:echoserver, :echo) 
     GenServer.cast(:echoserver, :mumble) 
     GenServer.cast(:echoserver, :echo) 
    end 
end 

कारण यह iex में काम करता है कि iex जाल से बाहर निकलें है और आप एक और लाइन में टाइप करने की अनुमति देता है।

+1

ठीक है, बहुत घूमने और याक शेविंग के बाद, यह मेरी समस्या थी, अपर्याप्त के साथ: timer.sleeps। मैं एक नोबी मोड के साथ कर सकता था जो उन्हें सब कुछ के बाद जोड़ता है। मेरी एस्क्रिप्ट क्रैश हो जाती है: अगर मैं GenServer.start का उपयोग करता हूं तो गड़बड़ हो जाता है, लेकिन अगर मैं GenServer.start_link का उपयोग करता हूं तो यह त्रुटि की रिपोर्ट करता है और पुनरारंभ किए गए जेनसेवर के साथ चलता है। मुझे समझ में आया कि इसे दूसरी तरफ काम करना चाहिए लेकिन मैं पढ़ूंगा। धन्यवाद। –

3

एस्क्रिप्ट व्यवहार सही है। आप बस गायब हैं कि कैसे iex खोल "आपकी मदद करता है"।

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

दोनों खोल और राजकुमार पर्यवेक्षक इस तरह "मैं मर गया, तो आपको" संदेश संभाल सकता है। वे इस तरह के संदेशों को संसाधित करने की प्रक्रिया (लिंक की गई प्रक्रिया, मरने वाले नहीं) को बदलकर करते हैं। यह उन्हें सामान्य, आंतरिक लोगों के बजाय सामान्य संदेशों के रूप में प्राप्त करने की अनुमति देता है (यदि आप receive खंड में प्राप्त कर सकते हैं)। इस बहावौर को बदलने के लिए वे Process.flag(:trap_exit, :true) (elixir doceralng's one पर इंगित करते हैं) का उपयोग करें। यह शैल को सिर्फ मारे गए प्रक्रियाओं की मौत को मुद्रित करने की अनुमति देता है, बल्कि हर बार जब आप कुछ बुरा करते हैं तो मर जाते हैं।

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

आपको यह जानने की आवश्यकता नहीं है कि इसका उपयोग करने के लिए वेंडिंग मशीन को कैसे ठीक किया जाए।

तो के बजाय start

उस ने कहा, आप पर्यवेक्षक के साथ लिंक बनाने पर विचार कर सकते हैं, जो बहुत से पुनरारंभ करने के बाद भी मर सकता है (उसे इस तरह से व्यवहार करने के लिए कहा जा सकता है)। और यह आपको मरने पर उसे (और पर्यवेक्षित प्रक्रिया) लेने की अनुमति देता है। या वह आपके पर्यवेक्षक, या आवेदन पर्यवेक्षक, या किसी अन्य तरीके से जोड़ा जा सकता है। यह आपके डोमेन पर निर्भर करता है, और कोई बुरा निर्णय नहीं है, आपको सिर्फ यह जांचना होगा कि आपके लिए क्या काम कर रहा है।यह डिजाइन निर्णय है, और आप या तो प्रयोग करने के लिए है या इसके बारे में अधिक पढ़ सकते हैं:

http://elixir-lang.org/getting_started/mix_otp/5.html

http://www.erlang.org/doc/design_principles/des_princ.html

http://learnyousomeerlang.com/supervisors