2. Erlang
BUT FIRST...
AND OTP
IN ACTION
Buy this Book!
http://bit.ly/otp-book Martin Logan
Eric Merritt
Richard Carlsson
FOREWORD BY ULF WIGER
MANNING
3. Erlang
NO SERIOUSLY... IN ACTION
AND OTP
http://bit.ly/otp-book
Martin Logan
Eric Merritt
Richard Carlsson
FOREWORD BY ULF WIGER
MANNING
4. Erlang
AVAILABLE IN
PDF...
AND OTP
IN ACTION
http://bit.ly/otp-book
Martin Logan
Eric Merritt
Richard Carlsson
FOREWORD BY ULF WIGER
MANNING
9. CHLOE
• Realtime Web Server
• Proxies WebSocket (and fallback) connections to your app
• http://github.com/mashion/chloe
• Written in Erlang/OTP (plus a lot of JavaScript)
10. BAI PHILLY!
Leaving in July...
http://www.flickr.com/photos/dennis/156048151/
11. HAI CALIFORNIA!
See you in August...
http://www.flickr.com/photos/salim/402618628/
18. PATTERN MATCHING
Erlang Ruby
match_me(1) -> def match_me(val)
loneliest; case val
match_me(2) -> when 1
next_to_loneliest; :loneliest
match_me(friend) -> when 2
all_ok; :next_to_loneliest
match_me(_) -> when :friend
what_is_this. :all_ok
else
:what_is_this
end
end
19. MAKING A PROCESS
process.erl
concurrent_stuffs() ->
spawn(fun () -> timer:sleep(1000),
io:fwrite("So slown") end),
spawn(fun () -> io:fwrite("Super fastn") end).
erlang shell
5> process:concurrent_stuffs().
Super fast
<0.39.0>
So slow
50. VERTICAL SCALING
• Your processes will take advantage of all cores available
• Yay! No code changes required
51. HORIZONTAL SCALING
• New nodes added to the cluster can be auto-detected
• Code must know that a service could live on another node
• You’ll need resource discovery
53. SERVER REFERENCES
Type Definition
<Pid> globally unique process identifier
RegisteredName locally registered process
process locally registered on
{RegisteredName, Node}
another node
{global, GlobalName} globally registered process
54. LISTEN FOR INCOMING MESSAGE
listen() ->
register(listener, self()),
listen_loop().
listen_loop() ->
receive
{From, pizza} -> From ! "Nom noms", listen_loop();
{From, _} -> From ! "Boo!", listen_loop();
_ -> io:fwrite("Listen is dying!")
end.
55. SENDING MESSAGE TO NODES
$ erl -name b
1> AHost = 'a@awesome-town.local'.
'a@awesome-town.local'
2> {listener, AHost} ! {self(), pizza}.
ok
3> receive PizzaResp -> PizzaResp end.
56. RESOURCE DISCOVERY
Method Purpose
add_target_resource(Type) specify a resource type you want to use
add_local_resource(Type, Pid) specify a resource type you have
fetch_resources(Type) fetch all resources of specified type
trade_resources() trade resource information
See Chapter 8 of Erlang And OTP In Action
57. HORIZONTAL CAVEATS
• Passing large amounts of data between nodes is inefficient
• Too many nodes will impact performance (Keep it < 100)
• There are ways around both these problems
59. OTPWTFBBQ?
• Open Telecom Platform
• Abstracts common systems behavior (servers, supervisors, ...)
• Easier than pure Erlang!
• Gives Erlang its reputation for fault tolerance
60. BASIC CONSTRUCTS
Construct Purpose
Encapsulates a large set of code
Application
meant to run as one unit.
Supervisor Starts and restarts workers.
Worker Actually does stuff
62. WORKERS
• Use the `gen_server` behaviour (for the most part)
• Contain your application logic
• You define a module with callbacks
• OTP runs a server calls back to module when messages arrive
63. HOW WORKERS WORK
client process (your code)
gen_server functions
gen_server code (part of OTP)
gen_server callbacks
worker code (your code)
worker process
66. WORKER CALLBACKS
Callback Purpose
init(Args) Initialize the server process
handle_call(Request, From, State) Handle a synchronous call
handle_cast(Request, State) Handle an asynchronous cast
handle_info(Info, State) For timeouts and random messages
terminate(Reason, State) Clean up the process when it dies
code_change(OldVsn, State, Extra) Called when upgrading code
67. WORKER FUNCTIONS
Callback Purpose
start_link(Module, Args, Options) Start a supervised worker
start(Module, Args, Options) Start an unsupervised worker
call(ServerRef, Request, Timeout) Synchronously call a worker
cast(ServerRef, Request) Asynchronously cast to a worker
man gen_server
68. SUPERVISORS
• Use the `supervisor` behaviour
• Contain little to no application logic
• Know how to start and restart failed workers
• Keep your application from ever fully dying
81. RESTART STRATEGIES
Strategy When a child dies....
one_for_one restart it
one_for_all restart all children
restart it and all children after it
rest_for_one
in child list
restart it (also allows you to
simple_one_for_one
dynamically add children)
105. SUPERVISOR FUNCTIONS
Callback Purpose
start_link(Module, Args) Start a supervised supervisor
start_child(SupRef, ChildSpec) Start a child under the supervisor
man supervisor
106. FAULT TOLERANCE
• When you hit an error, let the worker die
• Supervisor will restart it
• Either try what killed it again or move on
• Life is grand