Elixir 1.7 - Supervisor

पर्यवेक्षक का व्यवहार




elixir

पर्यवेक्षक का व्यवहार

पर्यवेक्षकों को लागू करने के लिए एक व्यवहार मॉड्यूल।

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

एक पर्यवेक्षक को start_link/2 माध्यम से सीधे बच्चों की सूची के साथ शुरू किया जा सकता है या आप एक मॉड्यूल-आधारित पर्यवेक्षक को परिभाषित कर सकते हैं जो आवश्यक कॉलबैक को लागू करता है। अधिकांश उदाहरणों में पर्यवेक्षकों को शुरू करने के लिए नीचे के खंड start_link/2 का उपयोग करते हैं, लेकिन इसमें मॉड्यूल-आधारित लोगों पर एक विशिष्ट अनुभाग भी शामिल है।

उदाहरण

पर्यवेक्षक शुरू करने के लिए, हमें सबसे पहले एक बच्चे की प्रक्रिया को परिभाषित करने की आवश्यकता है जिसकी देखरेख की जाएगी। एक उदाहरण के रूप में, हम एक GenServer को परिभाषित करेंगे जो एक स्टैक का प्रतिनिधित्व करता है:

defmodule Stack do
  use GenServer

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

  ## Callbacks

  @impl true
  def init(stack) do
    {:ok, stack}
  end

  @impl true
  def handle_call(:pop, _from, [head | tail]) do
    {:reply, head, tail}
  end

  @impl true
  def handle_cast({:push, head}, tail) do
    {:noreply, [head | tail]}
  end
end

स्टैक सूचियों के चारों ओर एक छोटा आवरण है। यह हमें सूची में शामिल होने के द्वारा, स्टैक के शीर्ष पर एक तत्व लगाने और पैटर्न मिलान के साथ स्टैक के शीर्ष पर पहुंचने की अनुमति देता है।

हम अब एक पर्यवेक्षक शुरू कर सकते हैं जो हमारी स्टैक प्रक्रिया को शुरू और पर्यवेक्षण करेगा। पहला कदम बाल विनिर्देशों की एक सूची को परिभाषित करना है जो नियंत्रित करता है कि प्रत्येक बच्चा कैसे व्यवहार करता है। प्रत्येक बाल विनिर्देश एक नक्शा है, जैसा कि नीचे दिखाया गया है:

children = [
  # The Stack is a child started via Stack.start_link([:hello])
  %{
    id: Stack,
    start: {Stack, :start_link, [[:hello]]}
  }
]

# Now we start the supervisor with the children and a strategy
{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)

# After started, we can query the supervisor for information
Supervisor.count_children(pid)
#=> %{active: 1, specs: 1, supervisors: 0, workers: 1}

ध्यान दें कि जेनरवर को शुरू करते समय, हम इसे Stack नाम से पंजीकृत कर रहे हैं, जो हमें इसे सीधे कॉल करने और स्टैक पर क्या मिलता है:

GenServer.call(Stack, :pop)
#=> :hello

GenServer.cast(Stack, {:push, :world})
#=> :ok

GenServer.call(Stack, :pop)
#=> :world

हालांकि, हमारे स्टैक सर्वर में एक बग है। अगर हम कहते हैं :pop और स्टैक खाली है, तो यह क्रैश होने वाला है क्योंकि कोई भी क्लॉज मैच नहीं करता है:

GenServer.call(Stack, :pop)
** (exit) exited in: GenServer.call(Stack, :pop, 5000)

सौभाग्य से, चूंकि सर्वर की देखरेख पर्यवेक्षक द्वारा की जा रही है, पर्यवेक्षक स्वचालित रूप से एक नया शुरू करेगा, जिसका प्रारंभिक स्टैक [:hello] :

GenServer.call(Stack, :pop)
#=> :hello

पर्यवेक्षक विभिन्न रणनीतियों का समर्थन करते हैं; ऊपर के उदाहरण में, हमने चुना है :one_for_one । इसके अलावा, प्रत्येक पर्यवेक्षक के पास बच्चों के रूप में कई कार्यकर्ता और / या पर्यवेक्षक हो सकते हैं, जिनमें से प्रत्येक का अपना कॉन्फ़िगरेशन है (जैसा कि "बाल विनिर्देश" अनुभाग में उल्लिखित है)।

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

शुरू करें और बंद करें

जब पर्यवेक्षक शुरू होता है, तो यह सभी बाल विशिष्टताओं का पता लगाता है और फिर प्रत्येक बच्चे को उस क्रम में शुरू करता है जिसे वे परिभाषित करते हैं। यह चाइल्ड स्पेसिफिकेशन में :start और आमतौर पर start_link/1 लिए डिफॉल्ट के तहत परिभाषित फ़ंक्शन को कॉल करके किया जाता है।

start_link/1 (या एक कस्टम) को तब प्रत्येक बच्चे की प्रक्रिया के लिए कहा जाता है। start_link/1 फ़ंक्शन को {:ok, pid} वापस करना होगा जहां pid एक नई प्रक्रिया की प्रक्रिया पहचानकर्ता है जो पर्यवेक्षक से जुड़ा हुआ है। बच्चे की प्रक्रिया आमतौर पर init/1 कॉलबैक निष्पादित करके अपना काम शुरू करती है। सामान्यतया, init कॉलबैक वह है जहां हम चाइल्ड प्रोसेस को इनिशियलाइज़ और कॉन्फ़िगर करते हैं।

शटडाउन प्रक्रिया रिवर्स ऑर्डर में होती है।

जब एक पर्यवेक्षक बन्द हो जाता है, तो यह सभी बच्चों को उनके द्वारा सूचीबद्ध विपरीत क्रम में समाप्त कर देता है। टर्मिनेशन एक शटडाउन एग्जिट सिग्नल भेजने से होता है, चाइल्ड प्रोसेस के लिए Process.exit(child_pid, :shutdown) माध्यम से, और फिर बच्चे की प्रक्रिया को समाप्त करने के लिए एक समय अंतराल की प्रतीक्षा करता है। यह अंतराल 5000 मिलीसेकंड तक डिफॉल्ट करता है। यदि बच्चे की प्रक्रिया इस अंतराल में समाप्त नहीं होती है, तो पर्यवेक्षक अचानक बच्चे को तर्क के साथ समाप्त करता है :kill । शटडाउन समय को बाल विनिर्देश में कॉन्फ़िगर किया जा सकता है जो अगले खंड में पूरी तरह से विस्तृत है।

यदि बच्चा प्रक्रिया बाहर नहीं फँस रही है, तो यह पहली निकास संकेत प्राप्त होने पर तुरंत बंद हो जाएगा। यदि बच्चा प्रक्रिया से बाहर निकल रहा है, तो terminate कॉलबैक लागू किया जाता है, और पर्यवेक्षक द्वारा अचानक समाप्त किए जाने से पहले बच्चे की प्रक्रिया को उचित समय अंतराल में समाप्त करना चाहिए।

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

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

बाल विनिर्देश

चाइल्ड स्पेसिफिकेशन बताता है कि सुपरवाइज़र कैसे शुरू करता है, शट डाउन करता है और चाइल्ड प्रोसेस को फिर से शुरू करता है।

बच्चे के विनिर्देशन में 6 कुंजी हैं। पहले दो आवश्यक हैं, और शेष वैकल्पिक हैं:

  • :id - पर्यवेक्षक द्वारा आंतरिक रूप से बच्चे के विनिर्देश की पहचान करने के लिए इस्तेमाल किया जाने वाला कोई भी शब्द; दिए गए मॉड्यूल में चूक। परस्पर विरोधी :id मानों के मामले में, पर्यवेक्षक आरंभिक आईडी के लिए मना कर देगा और इसकी आवश्यकता होगी। यह कुंजी आवश्यक है।

  • :start - बच्चे की प्रक्रिया शुरू करने के लिए मॉड्यूल-फ़ंक्शन-आर्ग के साथ एक ट्यूपल। यह कुंजी आवश्यक है।

  • :restart - एक परमाणु जो तब समाप्त होता है जब एक समाप्त बच्चे की प्रक्रिया को फिर से शुरू किया जाना चाहिए (नीचे "पुनरारंभ करें मान" अनुभाग देखें)। यह कुंजी वैकल्पिक और डिफ़ॉल्ट है :permanent

  • :shutdown - एक परमाणु जो परिभाषित करता है कि एक बच्चे की प्रक्रिया कैसे समाप्त की जानी चाहिए (नीचे "शटडाउन मान" अनुभाग देखें)। यह कुंजी वैकल्पिक है और चूक 5000 यदि प्रकार है :worker या :infinity यदि प्रकार है :supervisor

  • :type - निर्दिष्ट करता है कि बच्चे की प्रक्रिया एक :worker या एक :supervisor । यह कुंजी वैकल्पिक है और :worker लिए चूक है।

एक छठी कुंजी है :modules , कि शायद ही कभी बदल जाता है। यह स्वचालित रूप से मूल्य के आधार पर सेट किया जाता है :start

आइए समझते हैं :shutdown और :restart विकल्प नियंत्रण।

शटडाउन मान (शटडाउन)

निम्नलिखित शट डाउन मान का समर्थन किया जाता है :shutdown विकल्प:

  • :brutal_kill - बच्चे की प्रक्रिया बिना शर्त है और तुरंत Process.exit(child, :kill) का उपयोग करके समाप्त कर दिया गया है।

  • किसी भी पूर्णांक> = 0 - मिलीसेकंड में समय की वह मात्रा जो पर्यवेक्षक एक Process.exit(child, :shutdown) सिग्नल को Process.exit(child, :shutdown) बाद बच्चों के समाप्त होने की प्रतीक्षा करेगा। यदि बच्चा प्रक्रिया से बाहर नहीं निकल रहा है, तो प्रारंभिक :shutdown संकेत तुरंत बच्चे की प्रक्रिया को समाप्त कर देगा। यदि बच्चा प्रक्रिया से बाहर निकल रहा है, तो उसे समाप्त करने के लिए मिलीसेकंड में समय दिया गया है। यदि यह निर्दिष्ट समय के भीतर समाप्त नहीं होता है, तो चाइल्ड प्रोसेस को पर्यवेक्षक द्वारा Process.exit(child, :kill) माध्यम से बिना शर्त समाप्त कर दिया जाता है।

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

पुनः आरंभ मान (: पुनः आरंभ करें)

:restart विकल्प नियंत्रित करता है कि पर्यवेक्षक को सफल समापन माना जाना चाहिए या नहीं। यदि समाप्ति सफल है, तो पर्यवेक्षक बच्चे को पुनः आरंभ नहीं करेगा। यदि बच्चा प्रक्रिया दुर्घटनाग्रस्त हो जाती है, तो पर्यवेक्षक एक नई शुरुआत करेगा।

निम्न पुनरारंभ मानों का समर्थन किया जाता है :restart विकल्प:

  • :permanent - बच्चे की प्रक्रिया हमेशा पुनरारंभ होती है।

  • :temporary - पर्यवेक्षण प्रक्रिया की परवाह किए बिना बच्चे की प्रक्रिया को फिर से शुरू किया जाता है: किसी भी समाप्ति (यहां तक ​​कि असामान्य) को सफल माना जाता है।

  • :transient - बच्चे की प्रक्रिया को फिर से शुरू किया जाता है, जब वह असामान्य रूप से समाप्त हो जाता है, अर्थात, बाहर निकलने के कारण के अलावा :normal :shutdown , या {:shutdown, term}

बाहर निकलने के कारणों और उनके प्रभाव की अधिक संपूर्ण समझ के लिए, "कारणों और पुनरारंभ से बाहर निकलें" अनुभाग देखें।

child_spec / 1

पर्यवेक्षक शुरू करते समय, हम बाल विनिर्देशों की एक सूची पास करते हैं। वे विनिर्देशन मानचित्र हैं जो बताते हैं कि पर्यवेक्षक को अपने प्रत्येक बच्चे को कैसे शुरू करना, रोकना और फिर से शुरू करना चाहिए:

%{
  id: Stack,
  start: {Stack, :start_link, [[:hello]]}
}

ऊपर दिए गए नक्शे में एक पर्यवेक्षक को परिभाषित किया गया है :id Stack of Stack जिसे Stack.start_link([:hello]) कहकर शुरू किया गया है।

हालाँकि, नक्शे के रूप में प्रत्येक बच्चे के लिए बच्चे के विनिर्देश को निर्दिष्ट करना काफी त्रुटि वाला हो सकता है, क्योंकि हम स्टैक कार्यान्वयन को बदल सकते हैं और इसके विनिर्देश को अपडेट करना भूल सकते हैं। यही कारण है कि अमृत आपको विनिर्देशन के बजाय मॉड्यूल नाम और start_link तर्क के साथ एक टपल पास करने की अनुमति देता है:

children = [
  {Stack, [:hello]}
]

पर्यवेक्षक तब Stack.child_spec([:hello]) को एक बच्चे के विनिर्देश को पुनः प्राप्त करने के लिए आमंत्रित करेगा। अब Stack मॉड्यूल अपने स्वयं के विनिर्देशन के निर्माण के लिए जिम्मेदार है। डिफ़ॉल्ट रूप से, का use GenServer एक Stack.child_spec/1 फ़ंक्शन को परिभाषित करता है जो वही चाइल्ड विनिर्देश देता है जो हमने पहले दिया था:

%{
  id: Stack,
  start: {Stack, :start_link, [[:hello]]}
}

बस एक बच्चे के रूप में Stack मॉड्यूल को पारित करना संभव है:

children = [
  Stack
]

जब केवल मॉड्यूल नाम दिया जाता है, तो यह {Stack, []} बराबर होता है। इस मामले में, हम एक बच्चे के विनिर्देश के साथ अंत करेंगे जो इस तरह दिखता है:

%{
  id: Stack,
  start: {Stack, :start_link, [[]]}
}

{Stack, [:hello]} या Stack द्वारा मैप स्पेसिफिकेशन को बदलकर, हम use GenServer द्वारा परिभाषित डिफ़ॉल्ट कार्यान्वयन का उपयोग करते हुए, Stack मॉड्यूल में चाइल्ड स्पेसिफिकेशन को एन्कैप्सुलेटेड use GenServer । अब हम अपने Stack कार्यकर्ता को अन्य डेवलपर्स के साथ साझा कर सकते हैं और वे कार्यकर्ता की निम्न-स्तरीय जानकारी के बारे में चिंता किए बिना इसे सीधे उनके पर्यवेक्षण के पेड़ में जोड़ सकते हैं।

कुल मिलाकर, बाल विनिर्देश निम्नलिखित में से एक हो सकता है:

  • बाल विनिर्देश का प्रतिनिधित्व करने वाला एक नक्शा - जैसा कि "बाल विनिर्देश" खंड में उल्लिखित है
  • पहले तत्व के रूप में एक मॉड्यूल के साथ एक ट्यूपल और दूसरे के रूप में शुरू होने वाला तर्क - जैसे {Stack, [:hello]} । इस स्थिति में, Stack.child_spec([:hello]) को चाइल्ड स्पेसिफिकेशन प्राप्त करने के लिए कहा जाता है
  • एक मॉड्यूल - जैसे Stack । इस स्थिति में, Stack.child_spec([]) को चाइल्ड स्पेसिफिकेशन प्राप्त करने के लिए कहा जाता है

यदि आपको यह निर्धारित करने की आवश्यकता है कि एक ट्यूपल या मॉड्यूल चाइल्ड स्पेसिफिकेशन को मैप में कैसे बदल सकता है या चाइल्ड स्पेसिफिकेशन को संशोधित कर सकता है, तो आप Supervisor.child_spec/2 फ़ंक्शन का उपयोग कर सकते हैं। उदाहरण के लिए, स्टैक को अलग से चलाने के लिए :id और a :shutdown मान 10 सेकंड (10_000 मिलीसेकंड):

children = [
  Supervisor.child_spec({Stack, [:hello]}, id: MyStack, shutdown: 10_000)
]

Supervisor.child_spec/2 ऊपर का कॉल निम्नलिखित विनिर्देश लौटाएगा:

%{
  id: MyStack,
  start: {Stack, :start_link, [[:hello]]},
  shutdown: 10_000
}

आप Stack मॉड्यूल में बाल विनिर्देश को कॉन्फ़िगर करने के लिए भी एक अलग :id या :shutdown मान को use GenServer का use GenServer करने के use GenServer विकल्प का use GenServer :

defmodule Stack do
  use GenServer, id: MyStack, shutdown: 10_000

उपरोक्त विकल्प Stack.child_spec/1 द्वारा परिभाषित Stack.child_spec/1 फ़ंक्शन को कस्टमाइज़ करेंगे। यह Supervisor.child_spec/2 फ़ंक्शन के समान विकल्पों को स्वीकार करता है।

आप पूरी तरह से स्टैक मॉड्यूल में child_spec/1 फ़ंक्शन को ओवरराइड कर सकते हैं और अपने स्वयं के चाइल्ड विनिर्देश को वापस कर सकते हैं। ध्यान दें कि कोई गारंटी नहीं है कि child_spec/1 फ़ंक्शन पर्यवेक्षक प्रक्रिया द्वारा बुलाया जाएगा, क्योंकि पर्यवेक्षक तक पहुंचने से पहले अन्य प्रक्रियाएं बच्चे के विनिर्देश को प्राप्त करने के लिए इसे लागू कर सकती हैं।

कारण और पुनरारंभ से बाहर निकलें

एक पर्यवेक्षक एक बच्चे की प्रक्रिया को इसके आधार पर :restart करता है :restart कॉन्फ़िगरेशन को :restart करें। उदाहरण के लिए, जब :restart लिए सेट किया गया है :transient , पर्यवेक्षक बच्चे को पुनः आरंभ नहीं करता है यदि यह कारण के साथ बाहर निकलता है :normal :shutdown या {:shutdown, term}

तो एक पूछ सकता है: बाहर निकलते समय मुझे कौन से बाहर का कारण चुनना चाहिए? तीन विकल्प हैं:

  • :normal - ऐसे मामलों में, निकास लॉग नहीं किया जाएगा, क्षणिक मोड में कोई पुनरारंभ नहीं है, और लिंक की गई प्रक्रियाएं बाहर नहीं निकलती हैं

  • :shutdown या {:shutdown, term} - ऐसे मामलों में, निकास लॉग नहीं किया जाएगा, क्षणिक मोड में कोई पुनरारंभ नहीं है, और लिंक किए गए प्रक्रिया एक ही कारण से बाहर निकलते हैं जब तक कि वे बाहर नहीं निकलते।

  • कोई अन्य शब्द - ऐसे मामलों में, निकास लॉग हो जाएगा, क्षणिक मोड में पुनरारंभ होते हैं, और लिंक किए गए प्रक्रिया एक ही कारण से बाहर निकलते हैं जब तक कि वे बाहर नहीं निकलते।

ध्यान दें कि अधिकतम पुनरारंभ तीव्रता तक पहुंचने वाला पर्यवेक्षक इसके साथ बाहर निकल जाएगा :shutdown कारण। इस मामले में पर्यवेक्षक को केवल तभी पुनरारंभ किया जाएगा जब उसके बच्चे के विनिर्देश को परिभाषित किया गया था :restart विकल्प :permanent (डिफ़ॉल्ट)।

मॉड्यूल-आधारित पर्यवेक्षक

ऊपर दिए गए उदाहरण में, पर्यवेक्षक संरचना को start_link/2 पास करके शुरू किया गया था। हालांकि, पर्यवेक्षकों को पर्यवेक्षण मॉड्यूल को स्पष्ट रूप से परिभाषित करके भी बनाया जा सकता है:

defmodule MyApp.Supervisor do
  # Automatically defines child_spec/1
  use Supervisor

  def start_link(arg) do
    Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
  end

  @impl true
  def init(_arg) do
    children = [
      {Stack, [:hello]}
    ]

    Supervisor.init(children, strategy: :one_for_one)
  end
end

दो दृष्टिकोणों के बीच का अंतर यह है कि एक मॉड्यूल-आधारित पर्यवेक्षक आपको पर्यवेक्षक को कैसे आरंभ किया जाता है, इस पर अधिक प्रत्यक्ष नियंत्रण देता है। बच्चों की एक सूची के साथ Supervisor.start_link/2 को कॉल करने के बजाय जो स्वचालित रूप से आरंभिक हैं, हमने मैन्युअल रूप से Supervisor.init/2 को इसके init/1 कॉलबैक के अंदर कॉल करके बच्चों को प्रारंभिक रूप से आरंभ किया।

use Supervisor child_spec/1 फ़ंक्शन को भी परिभाषित करता है जो हमें MyApp.Supervisor को किसी अन्य पर्यवेक्षक के बच्चे के रूप में चलाने की अनुमति देता है:

children = [
  MyApp.Supervisor
]

Supervisor.start_link(children, strategy: :one_for_one)

एक सामान्य दिशानिर्देश केवल पर्यवेक्षक के बिना आपके पर्यवेक्षण ट्री के शीर्ष पर, आमतौर पर Application.start/2 कॉलबैक में कॉलबैक मॉड्यूल का उपयोग करना है। हम आपके आवेदन में किसी अन्य पर्यवेक्षक के लिए मॉड्यूल-आधारित पर्यवेक्षकों का उपयोग करने की सलाह देते हैं, इसलिए वे पेड़ में एक और पर्यवेक्षण के बच्चे के रूप में चला सकते हैं। उत्पन्न child_spec/1 को निम्नलिखित विकल्पों के साथ अनुकूलित किया जा सकता है:

  • :id - बाल विनिर्देश पहचानकर्ता, वर्तमान मॉड्यूल में चूक
  • :start - बच्चे की प्रक्रिया कैसे शुरू करें ( __MODULE__.start_link/1 को कॉल करने के लिए चूक __MODULE__.start_link/1 )
  • :restart - जब पर्यवेक्षक को फिर से शुरू किया जाना चाहिए, चूक करना :permanent

अब तक हमने पर्यवेक्षक को एक एकल बच्चे के रूप में एक टपल के साथ-साथ एक रणनीति के रूप में पारित करना शुरू कर दिया है :one_for_one :

Supervisor.start_link([
  {Stack, [:hello]}
], strategy: :one_for_one)

या init/1 कॉलबैक के अंदर से:

Supervisor.init([
  {Stack, [:hello]}
], strategy: :one_for_one)

start_link/2 और init/2 को दिया गया पहला तर्क ऊपर दिए गए "child_spec / 1" अनुभाग में परिभाषित बाल विशिष्टताओं की एक सूची है।

दूसरा तर्क विकल्पों की एक खोजशब्द सूची है:

  • :strategy - पर्यवेक्षण रणनीति विकल्प। यह या तो हो सकता है :one_for_one :rest_for_one या :one_for_all । आवश्यक है। "रणनीतियाँ" अनुभाग देखें।

  • :max_restarts - एक समय सीमा में अधिकतम पुनरारंभ की अनुमति। 3 चूक।

  • :max_seconds - समय सीमा जिसमें :max_restarts लागू होता है। 5 चूक।

  • :name - पर्यवेक्षक प्रक्रिया को पंजीकृत करने के लिए एक नाम। GenServer के दस्तावेज़ में "नाम पंजीकरण" अनुभाग में समर्थित मानों की व्याख्या की गई है। वैकल्पिक।

रणनीतियाँ

पर्यवेक्षक विभिन्न पर्यवेक्षण रणनीतियों का समर्थन करते हैं :strategy ( :strategy विकल्प, जैसा कि ऊपर देखा गया है):

  • :one_for_one - यदि कोई बच्चा प्रक्रिया समाप्त करता है, तो केवल उस प्रक्रिया को पुनः आरंभ किया जाता है।

  • :one_for_all - यदि एक बच्चे की प्रक्रिया समाप्त हो जाती है, तो अन्य सभी बच्चे की प्रक्रिया समाप्त हो जाती है और फिर सभी बच्चे की प्रक्रिया (समाप्त एक सहित) को फिर से शुरू किया जाता है।

  • :rest_for_one - यदि एक बच्चे की प्रक्रिया समाप्त हो जाती है, तो समाप्त की गई बाल प्रक्रिया और बाकी बच्चे इसके बाद शुरू होते हैं, समाप्त हो जाते हैं और फिर से शुरू हो जाते हैं।

उपरोक्त में, प्रक्रिया समाप्ति असफल समापन को संदर्भित करती है, जो कि :restart विकल्प द्वारा निर्धारित की जाती है।

एक :simple_one_for_one स्ट्रैटेजी भी होती है, जिसका नाम है :simple_one_for_one जिसे :simple_one_for_one ने बदल दिया है। :simple_one_for_one पर्यवेक्षक के समान था :one_for_one लेकिन बच्चों को गतिशील रूप से संलग्न करने पर बेहतर सूट करता है। जब इस रणनीति का उपयोग किया गया था तो इस मॉड्यूल में कई कार्यों ने थोड़ा अलग व्यवहार किया। अधिक जानकारी और माइग्रेशन रणनीतियों के लिए DynamicSupervisor मॉड्यूल देखें।

नाम पंजीकरण

एक पर्यवेक्षक GenServer के समान नाम पंजीकरण नियमों के लिए GenServer GenServer के प्रलेखन में इन नियमों के बारे में और पढ़ें।

सारांश

प्रकार

child()
child_spec()

पर्यवेक्षक विनिर्देश

init_option()

start_link/2 और init/2 को दिए गए विकल्प

name()

पर्यवेक्षक का नाम

on_start()

start_link फ़ंक्शंस के मान लौटाएं

on_start_child()

start_child फ़ंक्शन के मान start_child

option()

start* कार्यों द्वारा उपयोग किए जाने वाले विकल्प मान

options()

start* कार्यों द्वारा उपयोग किए जाने वाले विकल्प

strategy()

समर्थित रणनीतियों

supervisor()

पर्यवेक्षक का संदर्भ

कार्य

child_spec (mod_or_map, overrides)

एक बच्चे के विनिर्देश बनाता है और ओवरराइड करता है

count_children(supervisor)

दिए गए पर्यवेक्षक के लिए गणना मानों वाला एक मानचित्र लौटाता है

delete_child (पर्यवेक्षक, child_id)

चाइल्ड स्पेसिफिकेशन को child_id द्वारा पहचाना जाता है

init/2

आरंभ करने के लिए बच्चों की एक सूची और विकल्पों का एक सेट प्राप्त करता है

restart_child (पर्यवेक्षक, child_id)

चाइल्ड प्रोसेस को child_id द्वारा पहचाना जाता है

start_child (पर्यवेक्षक, child_spec)

supervisor लिए एक बच्चे के विनिर्देश जोड़ता है और उस बच्चे को शुरू करता है

start_link/2

दिए गए बच्चों के साथ एक पर्यवेक्षक शुरू करता है

start_link (मॉड्यूल, arg, विकल्प \\ [])

दिए गए module और arg साथ एक मॉड्यूल-आधारित पर्यवेक्षक प्रक्रिया शुरू करता है

बंद करो (पर्यवेक्षक, कारण \\: सामान्य, मध्यांतर \\: अनंत)

दिए गए reason साथ दिए गए पर्यवेक्षक को समकालिक रूप से रोकता है

terminate_child (पर्यवेक्षक, child_id)

चाइल्ड आईडी द्वारा पहचाने गए दिए गए बच्चे को निर्देश देता है

which_children(supervisor)

दिए गए पर्यवेक्षक के सभी बच्चों के बारे में जानकारी के साथ एक सूची देता है

कॉलबैक

init/1

कॉलबैक सुपरवाइजर शुरू करने और हॉट कोड अपग्रेड के दौरान शुरू किया गया

प्रकार

बच्चे ()

child() :: pid() | :undefined

child_spec ()

child_spec() :: %{
  :id => atom() | term(),
  :start => {module(), atom(), [term()]},
  optional(:restart) => :permanent | :transient | :temporary,
  optional(:shutdown) => timeout() | :brutal_kill,
  optional(:type) => :worker | :supervisor,
  optional(:modules) => [module()] | :dynamic
}

पर्यवेक्षक विनिर्देश

init_option ()

init_option() ::
  {:strategy, strategy()}
  | {:max_restarts, non_neg_integer()}
  | {:max_seconds, pos_integer()}

start_link/2 और init/2 को दिए गए विकल्प

नाम ()

name() :: atom() | {:global, term()} | {:via, module(), term()}

पर्यवेक्षक का नाम

on_start ()

on_start() ::
  {:ok, pid()}
  | :ignore
  | {:error, {:already_started, pid()} | {:shutdown, term()} | term()}

start_link फ़ंक्शंस के मान लौटाएं

on_start_child ()

on_start_child() ::
  {:ok, child()}
  | {:ok, child(), info :: term()}
  | {:error, {:already_started, child()} | :already_present | term()}

start_child फ़ंक्शन के मान start_child

विकल्प ()

option() :: {:name, name()} | init_option()

start* कार्यों द्वारा उपयोग किए जाने वाले विकल्प मान

विकल्प ()

options() :: [option(), ...]

start* कार्यों द्वारा उपयोग किए जाने वाले विकल्प

रणनीति ()

strategy() :: :one_for_one | :one_for_all | :rest_for_one

समर्थित रणनीतियों

पर्यवेक्षक()

supervisor() :: pid() | name() | {atom(), node()}

पर्यवेक्षक का संदर्भ

कार्य

child_spec (mod_or_map, overrides)

child_spec(child_spec() | {module(), arg :: term()} | module(), keyword()) ::
  child_spec()

एक बच्चे के विनिर्देश बनाता है और ओवरराइड करता है।

start_link/2 और init/2 , यह एक module , {module, arg} या बाल विनिर्देश के रूप में एक मानचित्र की अपेक्षा करता है। यदि कोई मॉड्यूल दिया जाता है, तो विनिर्देशन को मॉड्यूल. module.child_spec(arg) कहकर पुनर्प्राप्त किया जाता है।

चाइल्ड स्पेसिफिकेशन के पुनर्प्राप्त होने के बाद, overrides पर खेतों को सीधे बच्चे की कल्पना पर लागू किया जाता है। यदि overrides में कुंजियाँ होती हैं जो किसी भी चाइल्ड स्पेसिफिकेशन फ़ील्ड में मैप नहीं होती हैं, तो एक त्रुटि उठाई जाती है।

ओवरराइडिंग के लिए उपलब्ध कुंजियों के लिए मॉड्यूल प्रलेखन में "चाइल्ड स्पेसिफिकेशन" अनुभाग देखें।

उदाहरण

इस फ़ंक्शन का उपयोग अक्सर एक :id विकल्प सेट करने के लिए किया जाता है, जब एक ही मॉड्यूल को पर्यवेक्षण ट्री में कई बार शुरू करने की आवश्यकता होती है:

Supervisor.child_spec({Agent, fn -> :ok end}, id: {Agent, 1})
#=> %{id: {Agent, 1},
#=>   start: {Agent, :start_link, [fn -> :ok end]}}

count_children (पर्यवेक्षक)

count_children(supervisor()) :: %{
  specs: non_neg_integer(),
  active: non_neg_integer(),
  supervisors: non_neg_integer(),
  workers: non_neg_integer()
}

दिए गए पर्यवेक्षक के लिए गणना मानों वाला एक मानचित्र लौटाता है।

मानचित्र में निम्नलिखित कुंजियाँ हैं:

  • :specs - बच्चों की कुल गिनती, मृत या जीवित

  • :active - इस पर्यवेक्षक द्वारा प्रबंधित सभी सक्रिय रूप से चलने वाली बाल प्रक्रियाओं की गिनती

  • :supervisors - सभी पर्यवेक्षकों की गिनती कि ये बाल पर्यवेक्षक अभी जीवित हैं या नहीं

  • :workers - सभी श्रमिकों की गिनती, ये बाल श्रमिक अभी भी जीवित हैं या नहीं

delete_child (पर्यवेक्षक, child_id)

delete_child(supervisor(), term()) :: :ok | {:error, error}
when error: :not_found | :simple_one_for_one | :running | :restarting

चाइल्ड स्पेसिफिकेशन को child_id द्वारा पहचाना जाता है।

संबंधित बाल प्रक्रिया नहीं चल रही होगी; अगर यह चल रहा है तो इसे समाप्त करने के लिए terminate_child/2 का उपयोग करें।

यदि सफल हो, तो यह फ़ंक्शन लौटाता है :ok । यदि child_id नहीं मिली है, या यदि वर्तमान प्रक्रिया चल रही है या फिर से चालू हो जाती है, तो यह फ़ंक्शन एक उचित त्रुटि के साथ एक त्रुटि लौटा सकता है।

init (बच्चे, विकल्प) (1.5.0 के बाद से)

init([:supervisor.child_spec() | {module(), term()} | module()], [init_option()]) ::
  {:ok, tuple()}

आरंभ करने के लिए बच्चों की एक सूची और विकल्पों का एक सेट प्राप्त करता है।

यह आमतौर पर मॉड्यूल-आधारित पर्यवेक्षकों के init/1 कॉलबैक के अंत में लगाया जाता है। अधिक जानकारी के लिए मॉड्यूल प्रलेखन में "मॉड्यूल-आधारित पर्यवेक्षकों" और "start_link / 2, init / 2 और रणनीतियों" अनुभाग देखें।

यह फ़ंक्शन सुपरवाइज़र फ़्लैग और चाइल्ड स्पेसिफिकेशंस युक्त एक टपल देता है।

उदाहरण

def init(_arg) do
  Supervisor.init([
    {Stack, [:hello]}
  ], strategy: :one_for_one)
end

विकल्प

  • :strategy - पर्यवेक्षण रणनीति विकल्प। यह या तो हो सकता है :one_for_one :rest_for_one :one_for_all , या पदावनत :simple_one_for_one

  • :max_restarts - एक समय सीमा में अधिकतम पुनरारंभ की अनुमति। 3 चूक।

  • :max_seconds - समय सीमा जिसमें :max_restarts लागू होता है। 5 चूक।

:strategy विकल्प की आवश्यकता होती है और डिफ़ॉल्ट रूप से 5 सेकंड के भीतर अधिकतम 3 पुनरारंभ की अनुमति होती है। उपलब्ध रणनीतियों के विस्तृत विवरण के लिए Supervisor मॉड्यूल की जाँच करें।

restart_child (पर्यवेक्षक, child_id)

restart_child(supervisor(), term()) ::
  {:ok, child()} | {:ok, child(), term()} | {:error, error}
when error: :not_found | :simple_one_for_one | :running | :restarting | term()

चाइल्ड प्रोसेस को child_id द्वारा पहचाना जाता है।

चाइल्ड स्पेसिफिकेशन मौजूद होना चाहिए और संबंधित चाइल्ड प्रोसेस नहीं चलना चाहिए।

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

यदि चाइल्ड प्रोसेस फंक्शन रिटर्न शुरू करता है {:ok, child} या {:ok, child, info} , तो PID को सुपरवाइज़र में जोड़ा जाता है और यह फ़ंक्शन समान मान लौटाता है।

यदि चाइल्ड प्रोसेस फंक्शन रिटर्न शुरू करता है :ignore , तो PID सेट पर रहता है :undefined और यह फ़ंक्शन रिटर्न करता है {:ok, :undefined}

यदि child_id नहीं मिली है, या यदि वर्तमान प्रक्रिया चल रही है या फिर से चालू हो जाती है, तो यह फ़ंक्शन एक उचित त्रुटि के साथ एक त्रुटि लौटा सकता है।

यदि चाइल्ड प्रोसेस स्टार्ट फ़ंक्शन फ़ंक्शन को एक त्रुटि या गलत मान देता है, या यदि यह विफल हो जाता है, तो यह फ़ंक्शन {:error, error}

start_child (पर्यवेक्षक, child_spec)

start_child(
  supervisor(),
  :supervisor.child_spec() | {module(), term()} | module() | [term()]
) :: on_start_child()

supervisor लिए एक बच्चे के विनिर्देश जोड़ता है और उस बच्चे को शुरू करता है।

child_spec एक वैध चाइल्ड child_spec होना चाहिए। बाल विनिर्देश में परिभाषित के रूप में बच्चे की प्रक्रिया शुरू की जाएगी।

यदि निर्दिष्ट आईडी वाली चाइल्ड स्पेसिफिकेशन पहले से मौजूद है, तो child_spec को छोड़ दिया जाता है और यह फ़ंक्शन :already_started :already_present ही चाइल्ड प्रोसेस चल रहा है या नहीं, तो :already_started या :already_present कोई त्रुटि देता है।

यदि चाइल्ड प्रोसेस फंक्शन रिटर्न शुरू करता है {:ok, child} या {:ok, child, info} , तो चाइल्ड स्पेसिफिकेशन और PID सुपरवाइजर में जुड़ जाते हैं और यह फंक्शन उसी वैल्यू को रिटर्न करता है।

यदि चाइल्ड प्रोसेस फंक्शन रिटर्न शुरू करता है :ignore , चाइल्ड स्पेसिफिकेशन सुपरवाइजर में जोड़ा जाता है, PID को सेट किया जाता है :undefined और यह फ़ंक्शन रिटर्न करता है {:ok, :undefined}

यदि चाइल्ड प्रोसेस स्टार्ट फंक्शन स्टार्ट करता है तो एक त्रुटि ट्यूपल या एक गलत मान देता है, या यदि यह विफल हो जाता है, तो चाइल्ड स्पेसिफिकेशन को छोड़ दिया जाता है और यह फंक्शन {:error, error} वापस आ जाता है {:error, error} जहाँ error एक टर्म है जिसमें एरर और चाइल्ड स्पेसिफिकेशन की जानकारी होती है।

start_link (बच्चे, विकल्प)

start_link(module(), term()) :: on_start()
start_link(
  [:supervisor.child_spec() | {module(), term()} | module()],
  options()
) :: on_start()

दिए गए बच्चों के साथ एक पर्यवेक्षक शुरू करता है।

बच्चे मॉड्यूल, तर्क और तर्क के साथ 2-तत्व ट्यूपल्स या चाइल्ड स्पेसिफिकेशन वाले नक्शे की एक सूची है। :strategy विकल्प के माध्यम से एक रणनीति प्रदान करने की आवश्यकता है। उदाहरण और अन्य विकल्पों के लिए "start_link / 2, init / 2 और रणनीतियों" देखें।

पर्यवेक्षक नाम पंजीकृत करने के लिए विकल्पों का भी उपयोग किया जा सकता है। समर्थित मान GenServer मॉड्यूल डॉक्स में "नाम पंजीकरण" अनुभाग के तहत वर्णित हैं।

यदि पर्यवेक्षक और उसके बच्चे की प्रक्रिया सफलतापूर्वक शुरू की जाती है (यदि प्रत्येक बच्चे की प्रक्रिया का प्रारंभ फ़ंक्शन {:ok, child} , {:ok, child, info} , या :ignore ) यह फ़ंक्शन देता है {:ok, pid} , जहां pid पर्यवेक्षक का पीआईडी ​​है। यदि पर्यवेक्षक को एक नाम दिया जाता है और निर्दिष्ट नाम के साथ एक प्रक्रिया पहले से मौजूद है, तो फ़ंक्शन {:error, {:already_started, pid}} , जहां pid उस प्रक्रिया का PID है।

यदि किसी भी बच्चे की प्रक्रिया का प्रारंभ कार्य विफल हो जाता है या त्रुटि ट्यूपल या एक गलत मान देता है, तो पर्यवेक्षक पहले कारण के साथ समाप्त होता है :shutdown सभी बच्चे प्रक्रियाओं को :shutdown कर दें जो पहले ही शुरू हो चुकी हैं, और फिर खुद को समाप्त कर देता है और {:error, {:shutdown, reason}}

ध्यान दें कि इस फ़ंक्शन के साथ शुरू किया गया एक पर्यवेक्षक मूल प्रक्रिया से जुड़ा हुआ है और न केवल क्रैश पर बाहर निकलता है, बल्कि अगर माता-पिता प्रक्रिया से बाहर निकलता है :normal कारण।

start_link (मॉड्यूल, arg, विकल्प \\ [])

start_link(module(), term(), GenServer.options()) :: on_start()

दिए गए module और arg साथ एक मॉड्यूल-आधारित पर्यवेक्षक प्रक्रिया शुरू करता है।

पर्यवेक्षक को शुरू करने के लिए, init/1 कॉलबैक को दिए गए module में लागू किया जाएगा, तर्क के रूप में। init/1 कॉलबैक को पर्यवेक्षक विनिर्देश वापस करना होगा जो कि init/2 फ़ंक्शन की सहायता से बनाया जा सकता है।

यदि init/1 कॉलबैक रिटर्न :ignore , तो यह फ़ंक्शन लौटता है :ignore साथ ही :ignore और पर्यवेक्षक कारण के साथ समाप्त होता है :normal । यदि यह विफल हो जाता है या एक गलत मान देता है, तो यह फ़ंक्शन {:error, term} देता है {:error, term} जहां term एक शब्द है जिसमें त्रुटि के बारे में जानकारी है, और पर्यवेक्षक कारण term साथ समाप्त होता है।

पर्यवेक्षक नाम को पंजीकृत करने के लिए :name विकल्प भी दिया जा सकता है, समर्थित मान GenServer मॉड्यूल डॉक्स में "नाम पंजीकरण" अनुभाग में वर्णित हैं।

बंद करो (पर्यवेक्षक, कारण \\: सामान्य, मध्यांतर \\: अनंत)

stop(supervisor(), reason :: term(), timeout()) :: :ok

दिए गए reason साथ दिए गए पर्यवेक्षक को समकालिक रूप से रोकता है।

यह लौटाता है :ok यदि पर्यवेक्षक दिए गए कारण के साथ समाप्त होता है तो :ok है। यदि यह किसी अन्य कारण से समाप्त होता है, तो कॉल बाहर निकलता है।

यह फ़ंक्शन त्रुटि रिपोर्टिंग के बारे में ओटीपी शब्दार्थ रखता है। यदि कारण इसके अलावा है :normal :shutdown या {:shutdown, _} , एक त्रुटि रिपोर्ट लॉग की गई है।

terminate_child (पर्यवेक्षक, child_id)

terminate_child(supervisor(), term()) :: :ok | {:error, error}
when error: :not_found | :simple_one_for_one

चाइल्ड आईडी द्वारा पहचाने गए दिए गए बच्चे को निर्देश देता है।

यदि एक है, तो प्रक्रिया समाप्त हो गई है। जब तक बच्चा अस्थायी नहीं होता तब तक चाइल्ड स्पेसिफिकेशन को रखा जाता है।

एक गैर-अस्थायी बच्चे की प्रक्रिया को बाद में पर्यवेक्षक द्वारा फिर से शुरू किया जा सकता है। बच्चे की प्रक्रिया को पुनरारंभ_चिल्ड restart_child/2 कॉल करके भी स्पष्ट रूप से पुनरारंभ किया जा सकता है। चाइल्ड स्पेसिफिकेशन निकालने के लिए delete_child/2 का उपयोग करें।

यदि सफल हो, तो यह फ़ंक्शन लौटाता है :ok । यदि दिए गए चाइल्ड आईडी के लिए कोई चाइल्ड स्पेसिफिकेशन नहीं है, तो यह फ़ंक्शन {:error, :not_found}

which_children (पर्यवेक्षक)

which_children(supervisor()) :: [
  {term() | :undefined, child() | :restarting, :worker | :supervisor,
   :supervisor.modules()}
]

दिए गए पर्यवेक्षक के सभी बच्चों के बारे में जानकारी के साथ एक सूची देता है।

ध्यान दें कि कम स्मृति स्थितियों के तहत बड़ी संख्या में बच्चों की निगरानी करते समय इस फ़ंक्शन को कॉल करना स्मृति अपवाद से बाहर हो सकता है।

यह फ़ंक्शन {id, child, type, modules} टुपल्स की सूची लौटाता है, जहां:

  • id - जैसा कि बाल विनिर्देश में परिभाषित किया गया है

  • child - संबंधित बच्चे की प्रक्रिया की पीआईडी :restarting यदि प्रक्रिया फिर से शुरू होने वाली है, या फिर :undefined ऐसी प्रक्रिया न होने पर :undefined

  • type - :worker या :supervisor , जैसा कि बाल विनिर्देश द्वारा निर्दिष्ट किया गया है

  • modules - बाल विनिर्देश द्वारा निर्दिष्ट के रूप में

कॉलबैक

init (args)

init(args :: term()) ::
  {:ok, {:supervisor.sup_flags(), [:supervisor.child_spec()]}} | :ignore

कॉलबैक सुपरवाइजर शुरू करने और हॉट कोड अपग्रेड के दौरान शुरू किया गया।

डेवलपर्स आमतौर पर उचित पर्यवेक्षण झंडे को वापस करने के लिए अपने init कॉलबैक के अंत में Supervisor.init/2 लागू करते हैं।