--- title: Reliability Features of Erlang transition: fade --- {% from "deckjs.html" import section with context %} {% call section('--------------- First Page ----------------------') %} ## Reliability Features of Erlang ### Lambda Lounge - Krakow, 2013 ### Garrett Smith @gar1t {% endcall %} {% call section('--------------- Intro ---------------------') %} # Confessions of an Imperative Programmer {% endcall %} {% call section('---------------- Stax ---------------------') %} # From *Software* to *System* {% endcall %} {% call section('-------------- Reliability ----------------') %} # Defining Reliability {% endcall %} {% call section('-------------- Monitoring -----------------') %} # The Monitor Problem {% endcall %} {% call section('------------- Enter Erlang ----------------') %} # Enter Erlang {% endcall %} {% call section('------------- Erlang Stay -----------------') %} # Erlang, Stay {% endcall %} {% call section('------------ Process Isolation ------------') %} # Process Isolation {% endcall %} {% call section('------------ Win31 Happy ------------------') %} ## Windows 3.1 - Happy State {% endcall %} {% call section('------------ Win31 Sad --------------------') %} ## Windows 3.1 - Sad State {% endcall %} {% call section('------------ Win31 Reboot -----------------') %} ## Windows 3.1 - Time to Reboot {% endcall %} {% call section('------------- Kernel Happy ----------------') %} ## Modern OS - Happy State {% endcall %} {% call section('------------- Kernel Happy 2 --------------') %} ## Modern OS - Also Happy State {% endcall %} {% call section('------------- Isolation -> Systems --------') %} ## Isolation => System {% endcall %} {% call section('------------- Failure ---------------------') %} ## Failure {% endcall %} {% call section('------------- Recovery --------------------') %} ## Recovery {% endcall %} {% call section('------------- Fault Intolerant ------------') %} ## Recoverable => Fault Intolerant {% endcall %} {% call section('------------- Fail Fast -------------------') %} ## "Let It Crash!" :::erlang {ok, DB} = connect() % E.g. {error, Error} will crash!
:::erlang case result() of I when is_integer(I) -> float(I); F when is_float(F) -> F % any other value will crash! end
:::erlang <<0,0,1,Rest/binary>> = read() % Starts with 0x00 0x00 0x01 or crash! {% endcall %} {% call section('------------- Map 1 -----------------------') %} ## Implications of Isolation {% endcall %} {% call section('------------- Map 2 -----------------------') %} ## Implications of Isolation {% endcall %} {% call section('------------- Map 3 -----------------------') %} ## Implications of Isolation {% endcall %} {% call section('------------- Map 4 -----------------------') %} ## Implications of Isolation {% endcall %} {% call section('------------- Map 5 -----------------------') %} ## Implications of Isolation {% endcall %} {% call section('------------- Map 6 -----------------------') %} ## Implications of Isolation {% endcall %} {% call section('------------- The Features ----------------') %} ## Reliability Features - Process Isolation - Assertive Programming (Fail Fast) - Process Supervision - Process Recovery {% endcall %} {% call section('------------- Demo System -----------------') %} ## Demo System {% endcall %} {% call section('------------- Demo System App -------------') %} ## Demo OTP App ### client.erl Single task that uses router to get a value ### router.erl Tries available servers using round-robin ### server.erl Provides a value; can have the sickness {% endcall %} {% call section('------------- Client ----------------------') %} ## client.erl :::erlang -module(client). start_link() -> e2_task:start_link(?MODULE, [], [registered, {repeat, ?REPEAT}]). handle_task(State) -> evaluate_result(get_value()), {repeat, State}. get_value() -> router:get_value(). evaluate_result({ok, Val}) -> e2_log:info("This is great. I got ~p~n", [Val]); evaluate_result({error, Err}) -> e2_log:error("I'm unhappy. I got this crap: ~p~n", [Err]). {% endcall %} {% call section('------------- Router ----------------------') %} ## router.erl :::erlang -module(router). start_link(Servers) -> e2_service:start_link(?MODULE, init_state(Servers), [registered]). get_value() -> e2_service:call(?MODULE, get). handle_msg(get, _From, State) -> {Reply, NextState} = try_servers(State), {reply, Reply, NextState}. {% endcall %} {% call section('------------- Round Robin -----------------') %} ## router.erl (cont) :::erlang try_servers([], State) -> {{'{{'}}error, no_servers}, State}; try_servers([Server|Rest], State) -> try_server(Server, Rest, State). try_server({N, Server}, Rest, State) -> try server:get_value(Server) of Resp -> {{'{{'}}ok, Resp}, next_server(N, State)} catch _:_ -> try_servers(Rest, State) end. next_server(N, #state{servers=Servers}=State) -> State#state{next_server=next_server_index(N, length(Servers))}. next_server_index(N, Max) when N == Max -> 1; next_server_index(N, Max) when N < Max -> N + 1. {% endcall %} {% call section('------------- Server ----------------------') %} ## server.erl :::erlang -module(server). start_link(N) -> e2_service:start_link(?MODULE, N, [{registered, name(N)}]). get_value(Server) -> e2_service:call(Server, get). handle_msg(get, _From, State) -> Value = value(State), {reply, apply_the_sickness(Value), State}. value(#state{n=N}) -> "reply from " ++ integer_to_list(N). {% endcall %} {% call section('------------- Server ----------------------') %} ## server.erl (cont) :::erlang apply_the_sickness(Value) -> case has_the_sickness() of true -> exit(blaaaaahh_i_have_the_sickness); false -> Value end. has_the_sickness() -> random:uniform(5) == 1. {% endcall %} {% call section('------------- Demo ------------------------') %} # Demo {% endcall %} {% call section('------------- Demo Recovery ---------------') %} ## Demo Recovery {% endcall %} {% call section('------------- Recap -----------------------') %} ## In A Nutshell - No reliability without isolation - Isolation changes *everything* - Isolation + recovery => fail fast - Isolation + independence => evolvable - More than reliable, survivable {% endcall %} {% call section('--------------- Not Only Erlang -----------') %} # Not Only Erlang!
(hint: OS + sockets / 0MQ) {% endcall %} {% call section('------------- Learn More ------------------') %} ## More **Follow on Twitter @gar1t** ### http://e2project.org Simplified view to OTP - makes everything easier ### http://gar1t.com More than a shameless plug ### http://erlang.org Still the best resource on the web for Erlang {% endcall %}