2016-08-18 10 views
6

GenServer.start_link/3 में मैं एक नाम पंजीकृत कर सकते स्थानीय स्तर पर इस तरह की एक प्रक्रिया के लिए एक परमाणु का उपयोग कर:GenServer.start_link/3 में {: through, module, term} का उपयोग करके नाम पंजीकरण करने का क्या फायदा है?

defmodule Worker do 
    use GenServer 

    def start_link do 
    GenServer.start_link(__MODULE__, nil, name: :worker) 
    end 
end 

तो मैं एक पर्यवेक्षक शुरू कर सकते हैं इस प्रक्रिया की निगरानी के लिए:

defmodule Boss do 
    use Supervisor 

    def init(_) do 
    children = [worker(Worker, [])] 
    supervise(children, strategy: :one_for_one) 
    end 
end 

अब मैं बनाना चाहते पर्यवेक्षक 3 Worker प्रक्रियाओं की निगरानी के लिए, इसलिए मुझे उन 3 प्रक्रियाओं को अद्वितीय नाम देने की आवश्यकता है, ताकि पर्यवेक्षक प्रक्रिया को पुनरारंभ कर सकें, यह हमेशा एक ही प्रतीकात्मक नाम का उपयोग करेगा।

मैं बस इस तरह अद्वितीय Worker प्रक्रिया नाम के लिए स्ट्रिंग प्रक्षेप का उपयोग कर सकते हैं:

defmodule Worker do 
    use GenServer 

    def start_link(id) do 
    GenServer.start_link(__MODULE__, nil, name: :"worker_#{id}") 
    end 
end 

तो इस तरह 3 प्रक्रियाओं की निगरानी:

defmodule Boss do 
    use Supervisor 

    def init(_) do 
    children = for id <- 1..3 do 
     worker(Worker, [id], id: id) 
    end 
    supervise(children, strategy: :one_for_one) 
    end 
end 

ऐसा लगता है कि उम्मीद से काम करता है।

Name Registration section के तहत जेनसेवर के लिए दस्तावेज़ में, यह कहता है कि आप नाम भी पंजीकृत करने के लिए {:via, module, term} का उपयोग कर सकते हैं।

{: के माध्यम से, मॉड्यूल, टर्म} - जेनसेवर तंत्र और नाम के साथ पंजीकृत है। : विकल्प के माध्यम से एक मॉड्यूल की अपेक्षा करता है जो register_name/2, unregister_name/1, whereis_name/1 और भेज/2 निर्यात करता है। एक ऐसा उदाहरण है: ग्लोबल मॉड्यूल जो के लिए इन कार्यों का उपयोग करता है प्रक्रियाओं के नामों और उनके संबंधित पिड की सूची रखते हुए एरलांग नोड्स के नेटवर्क के लिए विश्व स्तर पर उपलब्ध हैं।

हालांकि, ताकि :via विकल्प का उपयोग करने में आप एक मॉड्यूल register_name/2, unregister_name/1, whereis_name/1 और send/2 निर्यात करता है, जो केवल के रूप में ऊपर दिखाए गए स्ट्रिंग प्रक्षेप तकनीक का उपयोग करने के लिए की तुलना में बहुत बोझिल लगता है लागू करने के लिए की है।

तो मेरे सवाल है:

  1. क्या है का उपयोग कर नाम दर्ज करने के लाभ: बस स्ट्रिंग प्रक्षेप का उपयोग करने पर {के माध्यम से, मॉड्यूल, अवधि}?
  2. क्या नाम पंजीकरण करने के लिए :via विकल्प का उपयोग करने का कोई व्यावहारिक उदाहरण है?

उत्तर

1

:via टुपल्स का उपयोग करके आप उपनाम हैंडलिंग को अच्छी तरह से समाहित कर सकते हैं, और आपको एक निश्चित बिंदु देता है जहां आप प्रक्रियाओं को खोज सकते हैं। इसके अलावा, :via tuples मनमाने ढंग से जटिल हो सकता है, उदा। {:my_worker, 1} जैसे टुपल जो आमतौर पर स्ट्रिंग मैनिपुलेशन के साथ गड़बड़ करने के साथ काम करने के लिए अच्छे होंगे।

(ध्यान दें कि मैं अमृत सीख रहा हूँ, तो यह के लिए मेरे शब्द नहीं लेते। इसके अलावा, :via tuples के लिए मजबूत/बेहतर तर्क हो सकता है।)

1

मुख्य उदाहरण है जब आप करना चाहते हैं एक गैर-मानक नाम पंजीकरण पुस्तकालय का उपयोग करें। उदाहरण के लिए gproc library लें।यह :via का उपयोग करने के लिए इंटरफ़ेस आवश्यकताओं का पालन करता है, इसलिए आपके एप्लिकेशन कोड में न्यूनतम घुसपैठ की आवश्यकता होती है।

  1. एक प्रक्रिया उर्फ ​​
  2. के रूप में किसी भी शब्द का प्रयोग कई उपनाम
  3. गैर अद्वितीय गुण कई प्रक्रियाओं द्वारा एक साथ पंजीकृत किया जा सकता तहत एक प्रक्रिया रजिस्टर: इसके अलावा, यह मानक नाम पंजीकरण प्रणाली पर कई लाभ प्रदान करता है QLC और मैच विनिर्देश शब्दकोश
  4. का इंतजार पंजीकरण पर कुशल प्रश्नों के लिए इंटरफेस, चलो तुम जब तक प्रतीक्षा करें एक प्रक्रिया ही पंजीकृत करता
  5. atomically किसी अन्य प्रक्रिया को दूर पंजीकृत नाम और गुण दे
  6. काउंटर, और एकीकृत काउंटर, जो स्वचालित रूप से सभी काउंटरों की कुल दिए गए नाम के साथ
  7. वैश्विक रजिस्ट्री सब से ऊपर कार्यों नोड्स
  8. के एक नेटवर्क के लिए लागू के साथ बनाए रखने के

tl; डॉ - :via है आपको गैर-मानक प्रक्रिया पंजीकरण पुस्तकालयों का उपयोग करने की अनुमति देने के लिए। उन्हें एक इंटरफेस (जावा में एक इंटरफेस को लागू करने की तरह) के अनुरूप होना चाहिए, और अतिरिक्त कार्यक्षमता प्रदान कर सकते हैं।

1

एक परिदृश्य यह है कि जब आप अपने कर्मचारियों को गतिशील रूप से नाम असाइन करना चाहते हैं (शायद उन्हें simple_one_for_one पर्यवेक्षक द्वारा पर्यवेक्षित किया जाता है और समय के साथ गतिशील रूप से उत्पन्न होते हैं)।

क्योंकि परमाणु कभी कचरा इकट्ठा नहीं होते हैं, आप उन्हें उन श्रमिकों के नाम के रूप में उपयोग नहीं कर सकते हैं, अन्यथा आपको स्मृति रिसाव से निपटना होगा।

किसी कारण से, :global मॉड्यूल पर नाम पंजीकृत करने से मुझे असहज महसूस होता है क्योंकि वैश्विक राज्यों को अक्सर बुरा माना जाता है, खासकर एक अत्यधिक समवर्ती वातावरण में (यही कारण है कि आप एर्लांग/एलिक्सीर चुनते हैं)।

इसलिए इस मामले में, नामों को "नेमस्पेस" में पंजीकृत करना बेहतर होता है। {:via, module, term} ऐसे मामलों में विविधता चमकती है। module नामस्थान के रूप में कार्य करता है, और term कुछ भी हो सकता है (आमतौर पर एक स्ट्रिंग क्योंकि इसे समझना आसान है, और कचरा इकट्ठा किया जाता है)।

बीटीडब्ल्यू, यदि आप स्वयं रजिस्ट्री को लागू नहीं करना चाहते हैं, तो इस उद्देश्य के लिए पहले से ही एक मॉड्यूल Registry है। आपको बस रजिस्ट्री प्रक्रिया को एक नाम देने और इसकी निगरानी करने की आवश्यकता है।

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