PREviously on LAMBDA

base data types
processes
message passing (send/receive)
process registry
gen_server

TODAY

Erlang VM (BEAM) ecosystem
Erlang language extensions
OTP
let it crash!
clustering and distributed systems

Erlang VM (BEAM)

SMP and non-SMP BEAM versions
one SMP scheduler per thread per core by default
erl> erlang:system_info (cpu_topology). 

processes usually travel across schedulers

BEAM ECOSYSTEM

Erlang -> CoreErlang -> BEAM

<anyLanguage> [ -> CoreErlang ] -> BEAM
where <anyLanguage> can be:
LFE, Elixir, Joxa, Reia, ...
LuvvieScript
IDEA Object Database

Erjang (Erlang on JVM),
multiple BEAM emulators for JS

NIFs, ports, drivers, ...

Erlang language Extensions

In context of modules and data types,
we haven't mentioned yet:

namespaces
pmods
records
maps
behaviors

parse_transform, custom preprocesors, syntax tools

Open Telecom platform (OTP)

...has nothing to do with telco in fact :-)

gen_server reminder (call, cast, info)
gen_fsm (finite state machine)
gen_event (event handling)

applications, supervisors,
automatic failover

PRODUCTIVITY MATTERS


LET IT CRASH!

don't be defensive
pattern matching, tagged values
"normal" vs system messages

LIVE DEMO
process (node) monitoring
linked processes
monitor (process, node)
linked processes
process flags & trap_exit

supervisors, heartbeat

CRASH EXAMPLES

Fx1 = fun (Pid) -> monitor (process, Pid) end.
Fx2 = fun (Pid) -> link (Pid) end.
Fx3 = fun (Pid) -> link (Pid), process_flag (trap_exit, true) end.
Print = fun (Msg) -> io:format ("Received: ~p~n", [Msg]) end.

Test = fun (Fx) ->
  X = spawn (fun () ->
                 receive _ -> error ('X-crash-boom-bang!') end
             end),
  Y = spawn (fun () ->
                 Fx (X),
                 receive Msg -> Print (Msg) end
             end),
  X ! hello
end.
[ Test (F) || F <- [Fx1, Fx2, Fx3] ].


RECONSTRUCT PRE-CRASH STATE

shared nothing
processes may eventually die
process restarts with an empty state

so how to get back the state?

solution: ETS, DETS, Mnesia, ...

ETS heir and ownership transfers
state manager server

NODE MONITORING

toolbar, appmon, observer,
os_mon

CLUSTERING

JCL (^G)
epmd

  $ erl -sname foo
  $ erl -sname boo -remsh foo@gersemi 
node/0, nodes/0, get_cookie/0, set_cookie/2,
~/.erlang.cookie

Cluster boot example

LIVE CODE UPGRADES

l (my_module)
code, code_server
weberp:upgrade/0
erlang releases

DEMO TIME: DISTRIBUTED WEBSOCKETS

DWS gen_servers:
dws_ets_table_manager
dws_service_broker
dws_session_server

Cowboy handlers:
dws_session_handler
dws_websocket_handler

Demo WebSocket API:
dws_service_example

DWS: DISTRIBUTED SESSIONS

Mnesia-powered session storage

all the rest is node-specific
(service broker per-API state [metrics or so],
websocket connection state,
etc.)

if the currently connected node dies,
the websocket client just reconnects
(to the same [restarted] or any other node)

DWS: let's CRASH!

unknown message to dws_session_server:
erl> dws_session_server ! foo.
nothing crashed, it's defensive :-)

unexpected message to dws_service_broker:
erl> dws_service_broker ! foo.
17:37:21.181 [info] dws_ets_table_manager: received ETS ownership request: {'ETS-TRANSFER',dws_service_broker_state,<0.911.0>,[]}
17:37:21.181 [info] dws_ets_table_manager: received ETS take-over request: {own,<0.20098.2>,dws_service_broker_state}
17:37:21.181 [info] dws_service_broker: received ETS ownership request: {'ETS-TRANSFER',dws_service_broker_state,<0.893.0>,reused}
...well, it crashed, gave the ETS table away, restarted and
got the ETS table back, so the state was preserved!

WHAT IF THE ENTIRE OS PROCESS DIED?

Then we have a heartbeat helper!

Just try to kill the BEAM VM running the DWS...
It will automatically restart in production mode
(not in 'console' mode).

Resources



LET'S GET IN TOUCH!









idea.cz • mumps.cz • openvms.cz

Lambda Meetup on Erlang/OTP: session #2

By Tomas Morstein

Lambda Meetup on Erlang/OTP: session #2

  • 1,840