Warning: strpos() [function.strpos]: Empty needle in /home/dealer/kasat/pkg/cahir/web/html/lib/plugins/translation2/action.php on line 53

Warning: Cannot modify header information - headers already sent by (output started at /home/dealer/kasat/pkg/cahir/web/html/lib/plugins/translation2/action.php:53) in /home/dealer/kasat/pkg/cahir/web/html/inc/actions.php on line 163
erlang:otp-supervisor [Krystian Bacławski Wiki]
 

Szablon nadzorcy procesów

Opis działania

Informacje ogólne

Proces nadzorcy służy do budowania drzew procesów. Procesami potomnymi nadzorcy mogą być:

  • gen_server,
  • gen_fsm,
  • gen_event,
  • supervisor,
  • procesy zaimplementowane zgodnie z wytycznymi OTP.

Proces supervisor odpowiada za nadzorowanie procesów potomnych tj.:

  • startowanie i zatrzymywanie,
  • restartowanie w przypadku awarii,
  • wymianę modułów z wywołaniami zwrotnymi.

Tak jak inne procesy OTP - nadzorca posiada interfejs śledzenia i odpluskwiania.

Nadzorca posiada dwie listy procesów potomnych:

  • statyczną - w trakcie startu odpala procesy z tej listy,
  • dynamiczną - procesy są dodawane lub usuwane z tej listy w trakcie działania nadzorcy.

Specyfikacja potomków

Listę zarządzanych procesów będziemy nazywać specyfikacją potomków.

Procesy ze specyfikacji potomków są:

  • startowane od lewej do prawej,
  • kończone od prawej do lewej.

Specyfikacja potomków ma następującą postać:

{{RestartStrategy,MaxR,MaxT},[ChildSpec]}
 
  ChildSpec = {Id,StartFunc,Restart,Shutdown,Type,Modules}
   Id = term()
   StartFunc = {Module,Fun,Args}
   Restart = permanent | transient | temporary
   Shutdown = brutal_kill | int()>=0 | infinity
   Type = worker | supervisor
   Modules = [Module] | dynamic

Strategia restartowania

Strategia restartowania określa co ma się stać z zarządzanymi procesami, jeśli jeden z nich zakończył swoje działanie.

  • one_for_one - zostanie wystartowany tylko proces, który się zakończył,
  • one_for_all - zostaną zakończone wszystkie procesy, a następnie wszystkie zostaną wystartowane,
  • rest_for_one - wszystkie procesy, które znajdują się w specyfikacji potomków po prawej stronie od zakończonego, zostaną zakończone; następnie restartowany jest zakończony proces i wszystkie następne,
  • simple_one_for_one - uproszczona wersja one_for_one, wszyscy potomkowie są dynamicznie dodawaną instancją pojedynczego procesu (posiadają identyczny kod).

Częstotliwość restartowania

Wyobraźmy sobie sytuację, w której jeden z potomków ciągle się kończy. Co będzie robił nadzorca?

Aby zapobiec sytuacji, w której będzie wiecznie restartował jakiś proces należy określić dopuszczalną możliwą częstotliwość restartowania procesu. Jeśli częstotliwość ta zostanie przekroczona, nadzorca zabije wszystkich potomków oraz zakończy swoje działanie - sygnalizując swojemu nadzorcy, że coś jest nie w porządku z poddrzewem, którym zarządza.

Parametry częstotliwości restartowana:

  • MaxR - maksymalna liczba restartów,
  • MaxT - okres, w którym mierzona jest liczba restartów.

Sposób restartowania

Co ma się stać z procesem, który się zakończył - może nie zawsze chcemy, żeby się zrestartował… dlatego potomków oznacza się flagą:

  • permanent - stały, zawsze restartowany po zakończeniu,
  • temporary - tymczasowy, nigdy nie następuje jego restart,
  • transient - krótkotrwały (?), restart tylko w przypadku awarii.

Procedura zamykania procesu jest następująca:

  • przy pomocy exit(Child,shutdown) do procesu potomnego przesyłane jest grzeczne żądanie zakończenia działania,
  • nadzorca czeka ustaloną ilość czasu,
  • po przekroczeniu limitu czasowego nadzorca używa exit(Child,kill) do zabicia nieposłusznego procesu.

Uwaga: brutal_kill od razu zabija proces.

Uwaga: W przypadku nadzorcy implementującego strategię simple_one_for_one dynamiczne dzieci nigdy nie są zamykane w sposób bezpośredni. Zamiast tego oczekuje się, że procesy te zakończą swoje działanie w wyniku otrzymania sygnału wyjścia od swojego nadzorcy.

Moduły

Proces aktualizacji oprogramowania wymaga by nadzorca znał listę modułów używanych w bieżącej chwili przez swoich potomków:

  • dla supervisor, gen_server, gen_fsm lista modułów składa się z jednego elementu - modułu
  • dla gen_event który może potencjalnie używać wielu modułów, wartość Modules powinna być równa dynamic.

Cześć uniwersalna

Potomkowie dynamicznie dodawani do nadzorcy powinni jako wynik funkcji start zwracać {ok,Child} lub {ok,Child,Info}

Startowanie

supervisor:start_link(Module, Args) -> Result
supervisor:start_link(SupName, Module, Args) -> Result

Argumenty i wynik są identyczne jak w przypadku reszty szablonów OTP.

Procesy potomne

Dodawanie

supervisor:start_child(SupRef, ChildSpec) ->
  {ok,Child} |
  {ok,Child,Info} |
  {error,Error} |
  {error,already_present} |
  {error,{already_started,Child}}

Dodaje dynamicznie utworzonego potomka do zarządzanego drzewa procesów. Jeśli nadzorca zostanie zrestartowany informacja o dynamicznie utworzonych potomkach przepada.

Usuwanie

supervisor:terminate_child(SupRef, Id) -> Result
supervisor:delete_child(SupRef, Id) -> Result
 
  Result = ok | {error,not_found} | {error,simple_one_for_one}

Wywołanie terminate_child/2 kończy działanie procesu Id i ewentualnie go restartuje (jeśli tak zostało zażądane w specyfikacji potomków).

Wywołanie delete_child/2 powoduje zakończenie procesu i usunięcie odpowiadającego mu wpisu w specyfikacji potomków. Jeśli nadzorca zostanie zrestartowany informacja ta zostaje utracona.

Restartowanie

supervisor:restart_child(SupRef, Id) -> Result
 
  Result = {ok,Child} | {ok,Child,Info} | {error,Error}
  Error = running | not_found | simple_one_for_one | term()

Restartuje proces o identyfikatorze Id zgodnie z zapamiętaną strategią.

Informacje

supervisor:which_children(SupRef) -> [{Id,Child,Type,Modules}]

Zwraca informację o wszystkich potomkach zaczepionych w tym nadzorcy.

supervisor:count_children(SupRef) -> [{specs, ChildSpecCount}, {active, ActiveProcessCount}, {supervisors, ChildSupervisorCount}, {workers, ChildWorkerCount}]

Liczba potomków:

  • ChildSpecCount - wszystkich (aktywnych i zabitych),
  • ActiveProcessCount - aktywnych,
  • ChildSupervisorCount - nadzorcy,
  • ChildWorkerCount - robotnicy.

Funkcje zwrotne

Moduł z funkcjami zwrotnymi w przypadku nadzorcy jest bardzo prosty i sprowadza się do wygenerowania specyfikacji potomków:

Module:init(Args) -> {ok,{{RestartStrategy,MaxR,MaxT},[ChildSpec]}} | ignore

Przykład

-module(ch_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
 
start_link() ->
   supervisor:start_link(ch_sup, []).
 
init(_Args) ->
   {ok, {
          {one_for_one, 1, 60},
          [
            {ch3, {ch3, start_link, []}, permanent, brutal_kill, worker, [ch3]}
          ]
        }}.

Źródła

 
erlang/otp-supervisor.txt · Last modified: 2010/05/11 14:03 by Krystian Bacławski
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-No Derivative Works 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki