Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Erlang Supervision Trees

755 views

Published on

Erlang supervision trees helps bring fault tolerance, recovery and robustness to erlang applications. The presentation goes through basic and advanced examples along with supervision strategies.

Published in: Technology
  • Be the first to comment

Erlang Supervision Trees

  1. 1. ERLANG SUPERVISION TREES Code examples at https://github.com/agrawalakhil/erlang-supervision-trees
  2. 2. HELLO! I am Akhil Agrawal Doing Erlang development for last five years Doing Ejabberd development for last eight months now Started BIZense in 2008 & Digikrit in 2015
  3. 3. Overview Erlang supervision trees helps bring fault tolerance, recovery and robustness to erlang applications 1
  4. 4. ERLANG SUPERVISION TREES Supervision strategy consists of two steps – first to form the supervision trees and then providing restart strategy at each level to follow when child dies, which could affect other children Supervision Strategies Supervisors can supervise workers and other supervisors forming supervision tree, while workers should never be used in any position except under another supervisor Supervision Trees Complete examples of supervisors from the opensource projects like rabbitmq, ejabberd and others to get some understanding of how supervisors are used in real world Complete Examples A supervisor is responsible for starting, stopping, and monitoring its child processes. The basic idea of a supervisor is that it is to keep its child processes alive by restarting them when necessary Basics
  5. 5. Basics – Erlang Supervision (Without Supervisor Behavior) Linked processes - terminating process sends an exit signal to all linked processes but for supervision, supervisor should also trap exits - process instead of exiting, receives message of the form: {'EXIT', From, Reason} start_link() -> SupPid = spawn(classic_sup, supervisor, [basic_worker, start_link, undefined]), register(classic_sup, SupPid), SupPid ! {'INIT'}, {ok, SupPid}. receive -> {'INIT'} -> process_flag(trap_exit, true), {ok, NewPid} = apply(Module, Function, []), link(NewPid), error_logger:info_msg("Initializing the worker with pid ~p~n", [NewPid]), supervisor(Module, Function, NewPid); {'EXIT', Pid, Reason} -> {ok, NewPid} = apply(Module, Function, []), link(NewPid), error_logger:info_msg("Process basic_worker pid ~p terminated due to ~p, new pid is ~p~n", [Pid, Reason, NewPid]), supervisor(Module, Function, NewPid); end.
  6. 6. Basics – Supervisor Behavior Supervisor Behavior – Standard process for implementing supervision and provides preconfigured supervision strategies Image from Erlang/OTP Supervision Presentation start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). %% Flags :: {Strategy, Intensity, Period} %% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules} init(_Args) -> SupFlags = {one_for_one, 1, 5}, ChildSpecs = [{basic_worker_spec, {basic_worker, start_link, []}, permanent, brutal_kill, worker, [basic_worker]}], {ok, {SupFlags, ChildSpecs}}.
  7. 7. Advanced – Multi-level Supervision Supervisors can form a tree by supervising other supervisors and workers SupFlags = {RestartStrategy, Intensity, Period}, ChildSpecs = [ %% advanced_worker {advanced_worker_spec, {advanced_worker, start_link, []}, permanent, brutal_kill, worker, [advanced_worker]}, %% basic_sup {basic_sup_spec, {basic_sup, start_link, []}, permanent, brutal_kill, supervisor, [basic_sup, basic_worker]}], {ok, {SupFlags, ChildSpecs}}. Image from Erlang/OTP Supervision Presentation
  8. 8. SUPERVISION STRATEGIES If a child process terminates, all other child processes are terminated, and then all child processes, including the terminated one, are restarted one_for_all It is a simplified one_for_one supervisor, where all child processes are dynamically added instances of the same process simple_one_for_one If a child process terminates, only that process is restarted one_for_one If a child process terminates, the rest of the child processes (that is, the child processes after the terminated process in start order) are terminated. Then the terminated child process and rest of child processes are restarted rest_for_one Erlang Supervision Strategies
  9. 9. Advanced – Supervision Strategy one_for_one If a child process terminates, only that process is restarted. start_link({RestartStrategy, Intensity, Period}) -> supervisor:start_link({local, ?SERVER}, ?MODULE, [{RestartStrategy, Intensity, Period}]). init(Args = [{RestartStrategy, Intensity, Period}]) -> SupFlags = {RestartStrategy, Intensity, Period}, one_for_one_test_() -> {foreachx, fun(Args) -> strategy_setup(Args) end, fun(Args, Pid) -> strategy_cleanup(Args, Pid) end, [ {{one_for_one, 1, 5}, named_advanced_worker_restarted("one_for_one_advanced_worker _restarted")}, {{one_for_one, 1, 5}, named_basic_sup_restarted("one_for_one_basic_sup_restarted") } ]}.
  10. 10. Advanced – Supervision Strategy one_for_all If a child process terminates, all other child processes are terminated, and then all child processes, including the terminated one, are restarted one_for_all_test_() -> {foreachx, fun(Args) -> strategy_setup(Args) end, fun(Args, Pid) -> strategy_cleanup(Args, Pid) end, [ {{one_for_all, 1, 5}, named_advanced_worker_restarted("one_f or_all_advanced_worker_restarted")}, {{one_for_all, 1, 5}, named_basic_sup_restarted("one_for_all _basic_sup_restarted")} ]}. Image from Erlang/OTP Supervision Presentation
  11. 11. Advanced – Supervision Strategy rest_for_one If a child process terminates, the rest of the child processes (that is, the child processes after the terminated process in start order) are terminated. Then the terminated child process and rest of child processes are restarted rest_for_one_test_() -> {foreachx, fun(Args) -> strategy_setup(Args) end, fun(Args, Pid) -> strategy_cleanup(Args, Pid) end, [ {{rest_for_one, 1, 5}, named_advanced_worker_restarted("rest_for_o ne_advanced_worker_restarted")}, {{rest_for_one, 1, 5}, named_basic_sup_restarted("rest_for_one_bas ic_sup_restarted")} ]}. http://learnyousomeerlang.com/supervisors http://ferd.ca/the-zen-of-erlang.html
  12. 12. Advanced – Supervision Strategy simple_one_for_one 1. Dynamic supervision 2. Essentially a process factory %% {simple_one_for_one, 2, 5} dynamic_worker_restarted(Name, Args) -> fun(Pid) -> {Name, fun() -> ?debugFmt("dynamic_worker_restarted for args ~p~n", [Args]), {ok, ChildPid1} = supervisor:start_child(Pid, []), {ok, ChildPid2} = supervisor:start_child(Pid, []), ?assertEqual(2, length(supervisor:which_children(Pid))), ?debugFmt("Supervisor children ~p~n", [supervisor:which_children(Pid)]), exit(ChildPid1, kill), timer:sleep(1000), ?assertEqual(2, length(supervisor:which_children(Pid))), ?debugFmt("Supervisor children ~p~n", [supervisor:which_children(Pid)]), exit(ChildPid2, kill), timer:sleep(1000), ?assertEqual(2, length(supervisor:which_children(Pid))), ?debugFmt("Supervisor children ~p~n", [supervisor:which_children(Pid)]) end} end.
  13. 13. SOME REFERENCES ◉ http://erlang.org/doc/design_principles/sup_princ.html ◉ http://www.slideshare.net/gamlidek/ceug-introduction-to-otp- behaviors-part-ii-supervisors ◉ http://learnyousomeerlang.com/building-applications-with-otp ◉ http://learnyousomeerlang.com/supervisors ◉ http://learnyousomeerlang.com/common-test-for-uncommon-tests ◉ https://github.com/Eonblast/Trinity ◉ https://www.erlang.org/course/concurrent-programming ◉ http://ferd.ca/the-zen-of-erlang.html ◉ https://github.com/youngkin/supervisiontest
  14. 14. THANKS! Any questions? You can find me at @digikrit / akhil@digikrit.com Special thanks to all the people who made and released these awesome resources for free:  Presentation template by SlidesCarnival  Presentation models by SlideModel  Erlang by Ericsson, RabbitMQ from Pivotal & Ejabberd from ProcessOne

×