Tydzień temu stworzyliśmy Supervisor jako moduł. Osobny fragment kodu, który umożliwił nam zarządzanie PingPong.Server
tak, że kiedy nam padł proces, automatycznie był on startowany. To wszystko dostajemy w elixir out-of-the-box. A dokładnie mówiąc w erlangu – zresztą dawałem linki do dokumentacji erlanga w tej sprawie.
Dziś zaś ten sam PingPong.Server
wykorzystamy w skrypcie – bez modułu. Będzie nam dużo prościej niż ostatnio, gdyż znamy już znaczną część API i parametrów. Teraz wystarczy, że to oprogramujemy.
Supervisor w skrypcie
Zacznijmy o odpalenia iex z załadowanym modułem PingPongServer.exs
:
iex PingPongServer.exes
Możemy sprawdzić czy dobrze załadowaliśmy nasz serwer podobnie jak w zeszłym tygodniu.
iex>PingPong.Server.start_link iex>PingPong.Server.ping
Jak to zrobicie to ubijcie proces servera:
iex>Process.whereis(:pingpong) |> Process.exit(:kill)
Skoro wiemy, że nasz serwer PingPong
działa, to możemy przystąpić do jego wykorzystania przez Supervisor. Jak pamiętacie, przy robieniu use Supervisor
, następowało głównie wstrzyknięcie:
import Supervisor.Spec
Który udostępnia takie metody jak wroker
, supervisor
czy supervise
. Zarówno worker
jak i supervisor
jest nam potrzebne by określić co nasze procesy dzieci mają robić. Czy to będzie praca nadzorowania innych procesów, czy też normalne wykonywanie pracy, nie ma znaczenia. Musimy jednak móc wywołać taką metodę. Można to zrobić za pomocą pełnej składki, lub skróconej (bez części Supervisor.Spec
). Ja osobiście wolę skróconą. Pierwszym krokiem więc będzie zaimportowanie modułu Supervisor.Spec
:
iex>import Supervisor.Spec
Mając już moduł dostępny, musimy określić listę procesów, które mają być nadzorowane. W tym celu tworzymy listę procesów i przypasowujemy (pamiętacie pattern maching?:)) ją do zmiennej :
iex>children = [ worker(PingPong.Server, [])]
Teraz, możemy wystartować z naszym Supervisor za pomocą metody Supervisor.start_link/2
:
start = Supervisor.start_link(children, strategy: :one_for_one)
Różnica w tym co my tutaj robimy a to co było tydzień temu jest taka, że nasz kod napotyka na guard z pattern matching, przez co wchodzimy do metody która:
- wywołuje
supervise
, zwracający schemat nadzorcy - wywołuje
start_link/3
podając dummy moduł jako pierwszy parameter
Dokładnie mówiąc, my wykonywaliśmy w zeszłym tygodniu takie o to kod:
Supervisor.start_link(__MODULE__, [])
Który trafiał pod start_link/3
, gdzie trzeci parametr był opcjonalny. Zaś nasz teraźniejszy kod zamieniany jest na:
spec = Supervisor.Spec.supervise(children, options) Supervisor.start_link(Supervisor.Default, spec, options)
Co też oznacza, że sami możemy tak napisać i będzie ok :)
W tym wypadku udaje nam się nie posiadać metody init/1
, a wszystko przez nadpisaną metodę start_link/2
.
To co my jeszcze zrobiliśmy to przypisaliśmy wynik start_link
do zmiennej start. Zawiera ona tuple, który określi czy udało się nam wystartować nadzorcę i jak tak, jaki jest jego PID
. Jakbyśmy chcieli, pobrać PID
nadzorcy to:
iex>{ :ok, pid} = start
Tutaj ważne jest to by było :ok
– inaczej może być :error
, a ten ma prawo mieć inną strukturę lub inne wartości w tuple. Teraz możemy zrobić kilka rzeczy. Po pierwsze, możemy wysłać nasz ping:
iex>PingPong.Server.ping
Możemy także zrobić to samo w zeszłym tygodniu:
Process.whereis(:pingpong) Process.whereis(:pingpong) |> Process.exit(:kill) Process.whereis(:pingpong) Process.whereis(:pingpong) |> Process.exit(:kill) Process.whereis(:pingpong)
I zobaczyć, że nasz PID
od serwera, ulega zmianie co ubicie, a to znaczy, że supervisor działa jak należy. A dzięki metodzie: Supervisor.count_children/1
, możemy dowiedzieć się ile tych naszych procesów działa:
iex>Supervisor.count_children(pid) %{active: 1, specs: 1, supervisors: 0, workers: 1}
Podsumowanie
Jak widać, nie jest trudno stworzyć Supervisor w iex
. Wcale do tego moduł nie jest potrzebny. Za to łatwiej jest nam pewne rzeczy konfigurować i z miejsca możemy zobaczyć jak nasz kod działa i czy działa tak jak by chcemy. Wykorzystując wiedzę z tych dwóch postów na temat Supervisor, za tydzień stworzymy aplikację trochę bardziej zaawansowaną pod względem struktury drzewka children. Wszystko po to by za dwa tygodnie pobawić się pewną fajną funkcją :)
Do przeczytania za tydzień! :)
[…] tym tygodniu wykorzystamy naszą wiedzę o supervisor i stworzymy aplikację wykorzystującą dwa sposoby tworzenia nadzorców. Ogólnie, celem jest stworzenie drzewka, które będzie nam potrzebne do […]
Comments are closed.