EMZETT.
Login

Kurz: Die Open Telecom Platform (OTP) ist das Rahmenwerk, das Erlang-Systeme robust macht.

Teil des Kurses Erlang

Kapitel 6 von 8 im Kurs Erlang. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Warum OTP?

Die Open Telecom Platform (OTP) ist das Rahmenwerk, das Erlang-Systeme robust macht: fertige Prozessmuster (Behaviours) für Server (gen_server), Zustandsautomaten (gen_statem), Ereignisse (gen_event) und Supervisor-Bäume, die abgestürzte Prozesse neu starten.

gen_server

Ein gen_server kapselt Zustand und beantwortet Anfragen. Er besteht aus Callback-Funktionen:

-behaviour(gen_server).
-export([main/1, init/1, handle_call/3, handle_cast/2]).
 
init(Start) -> {ok, Start}.
 
handle_call(stand, _Von, N) -> {reply, N, N};
handle_call({addiere, X}, _Von, N) -> {reply, N + X, N + X}.
 
handle_cast(zuruecksetzen, _N) -> {noreply, 0};
handle_cast({erhoehe, X}, N) -> {noreply, N + X}.
 
main(_) ->
    {ok, Pid} = gen_server:start_link(?MODULE, 10, []),
    io:format("~p~n", [gen_server:call(Pid, stand)]),
    io:format("~p~n", [gen_server:call(Pid, {addiere, 5})]),
    gen_server:cast(Pid, {erhoehe, 100}),
    io:format("~p~n", [gen_server:call(Pid, stand)]),
    gen_server:cast(Pid, zuruecksetzen),
    io:format("~p~n", [gen_server:call(Pid, stand)]),
    gen_server:stop(Pid).

Ausgabe:

10
15
115
0

call ist synchron (wartet auf Antwort), cast asynchron.

Supervisor

Ein Supervisor überwacht Kindprozesse und startet sie nach einem Absturz gemäß einer Strategie neu:

-behaviour(supervisor).
-export([main/1, init/1, start_arbeiter/0]).
 
init(_) ->
    Strategie = #{strategy => one_for_one, intensity => 5, period => 10},
    Kinder = [#{id => arbeiter, start => {?MODULE, start_arbeiter, []}, restart => permanent}],
    {ok, {Strategie, Kinder}}.
 
start_arbeiter() ->
    Pid = spawn_link(fun() -> schleife() end),
    register(arbeiter, Pid),
    {ok, Pid}.
 
schleife() ->
    receive
        {Von, ping} -> Von ! pong, schleife();
        absturz -> exit(boom)
    end.
 
main(_) ->
    logger:set_primary_config(level, none),
    {ok, Sup} = supervisor:start_link(?MODULE, []),
    Erster = whereis(arbeiter),
    arbeiter ! {self(), ping},
    receive pong -> io:format("pong~n") end,
    unlink(Sup),
    arbeiter ! absturz,
    timer:sleep(100),
    Zweiter = whereis(arbeiter),
    io:format("neu gestartet: ~p~n", [Erster =/= Zweiter]),
    arbeiter ! {self(), ping},
    receive pong -> io:format("pong nach Neustart~n") end,
    exit(Sup, shutdown).

Ausgabe:

pong
neu gestartet: true
pong nach Neustart

Strategien

StrategieWirkung
one_for_oneNur das abgestürzte Kind wird neu gestartet
one_for_allAlle Kinder werden neu gestartet
rest_for_oneDas abgestürzte und alle danach gestarteten Kinder
simple_one_for_one / dynamicViele gleichartige, dynamisch gestartete Kinder

Tipp

Baue Anwendungen als Supervisor-Baum: Fehler bleiben lokal, und das System erholt sich selbst. Das ist das Rezept hinter 99,9999999 % Verfügbarkeit.

Merke

  • gen_server kapselt Zustand mit init, handle_call und handle_cast
  • Supervisor starten Kinder nach Abstürzen neu
  • Strategien: one_for_one, one_for_all, rest_for_one
  • OTP-Anwendungen werden mit rebar3 gebaut und als Releases ausgeliefert

Übungsaufgabe

Baue einen gen_server, der Schlüssel-Wert-Paare speichert (put/get).

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Prozesse und Nachrichten

Weiter: ETS, Fehler und Praxisbeispiele

Alle Kapitel: Erlang im Überblick