1 hour dive into Erlang/OTP

Post on 27-Nov-2014

8504 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Introduction to Erlang and OTP

Transcript

1 hour dive into Erlang/OTP

@jvalduvieco @jordillonch

Problem domain

Lots of users

Lots of users

24x7x365

24x7x365

Lots of critical concurrent transactions

Lots of critical concurrent transactions

Hardware or softwarebreaks

Hardware or softwarebreaks

Lots of code changes

Lots of code changes

UnscalableUnmaintainable } code

UnscalableUnmaintainable } code

Maintenance/Debugin

production system

Maintenance/Debugin

production system

Does it sound to you?

The Erlang solution

Simplicity...

Minimize defensive programming

Typeless variables

Develop by contract

t-shirt function size

If����������� ������������������  a����������� ������������������  function����������� ������������������  does����������� ������������������  not����������� ������������������  fit����������� ������������������  on����������� ������������������  your����������� ������������������  t-shirt����������� ������������������  it����������� ������������������  is����������� ������������������  too����������� ������������������  long!

Single responsibility principle

No shared state between entities

High Concurrency

High ConcurrencyHigh concurrency

Light threads

Light threadshundreds of thousands of threads in one

machine with a good cpu scheduler

Light threadshundreds of thousands of threads in one

machine with a good cpu scheduler

Lt

Lt

Lt

Lt

Message passing

Lt

Lt

Lt

Message passingA shared nothing architecture that

communicates through message passing

Lt

Lt

Lt

Message passingA shared nothing architecture that

communicates through message passing

Lt

Lt

Lt

Process Mailbox

Lt

Lt

Lt

Process MailboxEvery process has a mailbox with incoming

messages, process take on convenience

Lt

Lt

Lt

No shared state

Lt

LtS

S

S

Lt

No shared stateEvery process its own internal state stored in

a variable avoiding lock contention

Lt

LtS

S

S

Soft realtime

Soft realtime

You have no strict guarantees on latency but language is designed

to have low latency

High availability

High availabilityHigh availability

Pa

Supervised processes

Pb

Pa

Supervised processesprocesses can be monitored by other

processes, handling its termination

Pb

Pb

Fail early

Pa

S

Pb

Fail earlyFail as soon as possible and let someone handle bad data, someone will restart you

Pa

S

Fail earlyFail as soon as possible and let someone handle bad data, someone will restart you

Pa

Pb2

S

Hot code update

Pa v1

S

Pb

Pc

Hot code updateprocesses code and data can be replaced

without loosing service

Pa v1

S

Pb

Pc

Hot code updateprocesses code and data can be replaced

without loosing service

Pa v1Pa v2

S

Pb

Pc

P

Distribution

Node

P

PP

P

Node

P

P

P

PP PP

P

DistributionProcesses run on nodes and can be located

wherever they are

Node

P

PP

P

Node

P

P

P

PP PP

How does it look like?

Show me the code!

Demo 1

Hands on

The shell

Type on your console:

erl

You should see:Erlang R16B (erts-5.10.1) [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Eshell V5.10.1 (abort with ^G)1>

Variables

Variables start Uppercase

Variables are immutable

Can contain any type

You can do things like...

1> Foo = 1.12> Foo = 2.** exception error: no match of right hand side value 2

1> Foo = 1.12> Foo = 2.** exception error: no match of right hand side value 2

Foo����������� ������������������  is����������� ������������������  bounded����������� ������������������  to����������� ������������������  1

1> Foo = 1.12> Foo = 2.** exception error: no match of right hand side value 2

Foo����������� ������������������  is����������� ������������������  bounded����������� ������������������  to����������� ������������������  1

Foo����������� ������������������  ==����������� ������������������  2����������� ������������������  ?

1> Foo = 1.12> Bar = 2.23> Foo = Bar.** exception error: no match of right hand side value 2

This is GREAT!

Now you have your basic error checking system implemented

Advanced types

[List]

[1,2,3,4,5,6]

You can do things like...

Iterate sequentially

1> MyList = [1,2,3,4].[1,2,3,4]2> [Head|Tail] = MyList.[1,2,3,4]3> Head.14> Tail.[2,3,4]

1> MyList = [1,2,3,4].[1,2,3,4]2> [Head|Tail] = MyList.[1,2,3,4]3> Head.14> Tail.[2,3,4]

1> MyList = [1,2,3,4].[1,2,3,4]2> [Head|Tail] = MyList.[1,2,3,4]3> Head.14> Tail.[2,3,4]

Do something to all or some items on a list

(list comprehensions)

1> MyList = [1, 2, 3, 4].[1,2,3,4]2> [X + 2 || X <- MyList, X > 2].[5,6]

[Strings]

A list

You can do things like...

1> MyString = "Erlang is not Ruby"."Erlang is not Ruby"

1> MyString = "Erlang is not Ruby"."Erlang is not Ruby"2> [Head2|Tail2] = MyString."Erlang is not Ruby"3> Head2.694> Tail2."rlang is not Ruby"

ASC����������� ������������������  =����������� ������������������  “E”

{Tuples}

{1,2,3}

Basic data container

random access

matcheable

You can do things like...

1> Mytuple = {1,2,3,4}.{1,2,3,4}2> A = 1.13> B = 2.24> {A,B,C,D} = {1,2,3,4}.{1,2,3,4}5> C.36> D.4

1> Mytuple = {1,2,3,4}.{1,2,3,4}2> A = 1.13> B = 2.24> {A,B,C,D} = {1,2,3,4}.{1,2,3,4}5> C.36> D.4

A����������� ������������������  and����������� ������������������  B����������� ������������������  arebounded����������� ������������������  variables

1> Mytuple = {1,2,3,4}.{1,2,3,4}2> A = 1.13> B = 2.24> {A,B,C,D} = {1,2,3,4}.{1,2,3,4}5> C.36> D.4

A����������� ������������������  and����������� ������������������  B����������� ������������������  arebounded����������� ������������������  variables

pattern����������� ������������������  matchingA==1?B==2?

1> Mytuple = {1,2,3,4}.{1,2,3,4}2> A = 1.13> B = 2.24> {A,B,C,D} = {1,2,3,4}.{1,2,3,4}5> C.36> D.4

A����������� ������������������  and����������� ������������������  B����������� ������������������  arebounded����������� ������������������  variables

pattern����������� ������������������  matchingA==1?B==2?

C����������� ������������������  and����������� ������������������  D����������� ������������������  are����������� ������������������  unbounded����������� ������������������  variables

functions

functions are types

single exit point

You can do things like...

foo_bar_func(Foo, Bar) -> Result = Foo + Bar, Result.

foo_bar_func(Foo, Bar) -> Result = Foo + Bar, Result.

This����������� ������������������  is����������� ������������������  a����������� ������������������  arity����������� ������������������  2����������� ������������������  function����������� ������������������  (2����������� ������������������  parameters)

foo_bar_func(Foo, Bar) -> Result = Foo + Bar, Result.

This����������� ������������������  is����������� ������������������  a����������� ������������������  arity����������� ������������������  2����������� ������������������  function����������� ������������������  (2����������� ������������������  parameters)

means����������� ������������������  that����������� ������������������  more����������� ������������������  code����������� ������������������  is����������� ������������������  to����������� ������������������  come

foo_bar_func(Foo, Bar) -> Result = Foo + Bar, Result.

This����������� ������������������  is����������� ������������������  a����������� ������������������  arity����������� ������������������  2����������� ������������������  function����������� ������������������  (2����������� ������������������  parameters)

means����������� ������������������  that����������� ������������������  more����������� ������������������  code����������� ������������������  is����������� ������������������  to����������� ������������������  come

means����������� ������������������  the����������� ������������������  function����������� ������������������  code����������� ������������������  has����������� ������������������  ended

foo_bar_func(Foo, Bar) -> Result = Foo + Bar, Result.

Single����������� ������������������  exit����������� ������������������  pointReturns����������� ������������������  Result

This����������� ������������������  is����������� ������������������  a����������� ������������������  arity����������� ������������������  2����������� ������������������  function����������� ������������������  (2����������� ������������������  parameters)

means����������� ������������������  that����������� ������������������  more����������� ������������������  code����������� ������������������  is����������� ������������������  to����������� ������������������  come

means����������� ������������������  the����������� ������������������  function����������� ������������������  code����������� ������������������  has����������� ������������������  ended

1> FooBar = fun(Foo, Bar) ->1> Foo + Bar1> end.#Fun<erl_eval.12.82930912>2> Result = FooBar(1, 2).3

atoms

A constant with name

lowercase

You can do things like...

1> ok.ok2> ko.ko3> ok =:= ko.false4> ok =:= ok.true

1> MyFuncOK = fun() -> {ok, 33} end.#Fun<erl_eval.20.82930912>2> MyFuncFail = fun() -> {error, bad_arg} end.#Fun<erl_eval.20.82930912>

3> {ok, Result} = MyFuncOK().{ok,33}4> {ok, Result2} = MyFuncFail().** exception error: no match of right hand side value {error,bad_arg}

1> MyFuncOK = fun() -> {ok, 33} end.#Fun<erl_eval.20.82930912>2> MyFuncFail = fun() -> {error, bad_arg} end.#Fun<erl_eval.20.82930912>

3> {ok, Result} = MyFuncOK().{ok,33}4> {ok, Result2} = MyFuncFail().** exception error: no match of right hand side value {error,bad_arg}

atoms

1> MyFuncOK = fun() -> {ok, 33} end.#Fun<erl_eval.20.82930912>2> MyFuncFail = fun() -> {error, bad_arg} end.#Fun<erl_eval.20.82930912>

3> {ok, Result} = MyFuncOK().{ok,33}4> {ok, Result2} = MyFuncFail().** exception error: no match of right hand side value {error,bad_arg}

atoms

errorchecking}

1> MyFuncOK = fun() -> {ok, 33} end.#Fun<erl_eval.20.82930912>2> MyFuncFail = fun() -> {error, bad_arg} end.#Fun<erl_eval.20.82930912>

3> {ok, Result} = MyFuncOK().{ok,33}4> {ok, Result2} = MyFuncFail().** exception error: no match of right hand side value {error,bad_arg}

atoms

errorchecking}

do����������� ������������������  they����������� ������������������  match?

modules

basic name spacing

public/private functions

You can do things like...

-module(cool_func).

-export([foo_bar_func/2]).

foo_bar_func (Foo, Bar) -> Result = Foo + Bar, {ok, Result}.

On your ${EDITOR} create cool_func.erl

On erlang shell type:

1> c("cool_module").{ok,cool_module}2> {ok, Result3} = cool_module:sum(33, 44).{ok,77}3> Result3.77

Too easy?

Let’s add some pattern matching on parameters!

area({square, Side}) -> {ok,Side * Side};area({circle, Radius}) -> % almost :-) {ok, 3 * Radius * Radius};area({triangle, A, B, C}) -> S = (A + B + C)/2, {ok, math:sqrt(S*(S-A)*(S-B)*(S-C))};area(Other) -> {error, invalid_object}.

area({square, Side}) -> {ok,Side * Side};area({circle, Radius}) -> % almost :-) {ok, 3 * Radius * Radius};area({triangle, A, B, C}) -> S = (A + B + C)/2, {ok, math:sqrt(S*(S-A)*(S-B)*(S-C))};area(Other) -> {error, invalid_object}.

means����������� ������������������  that����������� ������������������  there����������� ������������������  is����������� ������������������  another����������� ������������������  matching����������� ������������������  

posibility

area({square, Side}) -> {ok,Side * Side};area({circle, Radius}) -> % almost :-) {ok, 3 * Radius * Radius};area({triangle, A, B, C}) -> S = (A + B + C)/2, {ok, math:sqrt(S*(S-A)*(S-B)*(S-C))};area(Other) -> {error, invalid_object}.

means����������� ������������������  that����������� ������������������  there����������� ������������������  is����������� ������������������  another����������� ������������������  matching����������� ������������������  

posibility

mymodule:area({square, 10}).mymodule:area({circle, 10}).mymodule:area({triangle, 2, 2, 3.5}).

Want more?

Let’s add some recursion!

Want more?

Let’s add some recursion!

Erlang does not use loops

factorial(0) -> 1;factorial(N) -> N * factorial(N-1).

OTP

Oh, This is Perfect!

OTP is a set of rock solid architecture patterns, practices and tools

Improves the design, fault tolerance and

deployment of your app

Erlang is just a language, OTP makes it great for

the real world

Basic architecture patterns

Supervisor

S

P P P S

P P

Supervisor

S

P P P S

P P

Supervisor spawns processes and handles its death

gen_server

gs

P

P

P

gen_server

gs

P

P

P

Generic single threaded server

gen_fsm

gf

P

P

P

{S}

gf

gen_fsm

P

P

P

{S}

Generic Finite State Machine

gen_event

em

P

P

P

PP

P

gen_event

em

P

P

P

PP

P

Event handler, you can subscribe to events

More on OTP...

• File hierarchy

• Applications

• Releases

• Basic abstraction libraries (logging, system...)

Let’s see a gen_server in action!

Introducing Simple Key Value Store

A server that is able to store {Key,

Value} and retrieve them by Key

Demo II

ets

S

gsP

skvs diagram

ets

S

gsP

skvs diagram

Starting skvs

Go to skvs source directory

Compile./rebar compile

Start the Erlang nodeerl -pa ebin

Start the appapplication:start(skvs).

Some commands

Set a value

skvs_server:set(“Key”,”Value”).

skvs_server:set(“Key2”,”Value2”).

Get a value

skvs_server:get(“Key2”).

start_link() -> gen_server:start_link({local, skvs}, skvs_server, [], []).

get(Key) -> gen_server:call(skvs, {get, Key}).

set(Key,Value) -> gen_server:call(skvs, {set, Key, Value}).

set_fire_and_forget(Key,Value) -> gen_server:cast(skvs, {set, Key, Value}).

Code on client: skvs_server.erl

start_link() -> gen_server:start_link({local, skvs}, skvs_server, [], []).

get(Key) -> gen_server:call(skvs, {get, Key}).

set(Key,Value) -> gen_server:call(skvs, {set, Key, Value}).

set_fire_and_forget(Key,Value) -> gen_server:cast(skvs, {set, Key, Value}).

Code on client: skvs_server.erl

start����������� ������������������  gen_server

start_link() -> gen_server:start_link({local, skvs}, skvs_server, [], []).

get(Key) -> gen_server:call(skvs, {get, Key}).

set(Key,Value) -> gen_server:call(skvs, {set, Key, Value}).

set_fire_and_forget(Key,Value) -> gen_server:cast(skvs, {set, Key, Value}).

Code on client: skvs_server.erl

start����������� ������������������  gen_server

sync����������� ������������������  call����������� ������������������  to����������� ������������������  server(waits����������� ������������������  for����������� ������������������  reply)

start_link() -> gen_server:start_link({local, skvs}, skvs_server, [], []).

get(Key) -> gen_server:call(skvs, {get, Key}).

set(Key,Value) -> gen_server:call(skvs, {set, Key, Value}).

set_fire_and_forget(Key,Value) -> gen_server:cast(skvs, {set, Key, Value}).

Code on client: skvs_server.erl

start����������� ������������������  gen_server

async����������� ������������������  call����������� ������������������  to����������� ������������������  server(fire����������� ������������������  &����������� ������������������  forget)

sync����������� ������������������  call����������� ������������������  to����������� ������������������  server(waits����������� ������������������  for����������� ������������������  reply)

%% Client Callbacks on server%% Sync calls, expects responsehandle_call({set, Key, Value}, _From,State) -> {reply, set_value(Key,Value), State};handle_call({get, Key}, _From, State) -> {reply, get_value(Key), State}.

%% Async calls, do not expect responsehandle_cast({set, Key, Value}, State) -> set_value(Key,Value), {noreply, State}.

Callback code: skvs_server.erl

%% Client Callbacks on server%% Sync calls, expects responsehandle_call({set, Key, Value}, _From,State) -> {reply, set_value(Key,Value), State};handle_call({get, Key}, _From, State) -> {reply, get_value(Key), State}.

%% Async calls, do not expect responsehandle_cast({set, Key, Value}, State) -> set_value(Key,Value), {noreply, State}.

Callback code: skvs_server.erl

return����������� ������������������  value

%% Client Callbacks on server%% Sync calls, expects responsehandle_call({set, Key, Value}, _From,State) -> {reply, set_value(Key,Value), State};handle_call({get, Key}, _From, State) -> {reply, get_value(Key), State}.

%% Async calls, do not expect responsehandle_cast({set, Key, Value}, State) -> set_value(Key,Value), {noreply, State}.

Callback code: skvs_server.erl

return����������� ������������������  valueSurvives����������� ������������������  between����������� ������������������  

requests

%% Private functionsset_value(Key, Value) -> % Insert Key, Value into ETS. % Fail early {ok,Result}=case ets:insert(data_store,{Key,Value}) of true -> {ok, {Key,Value}}; {error, Reason} -> {error, Reason} end, Result.

Actual work...: skvs_server.erl

%% Private functionsset_value(Key, Value) -> % Insert Key, Value into ETS. % Fail early {ok,Result}=case ets:insert(data_store,{Key,Value}) of true -> {ok, {Key,Value}}; {error, Reason} -> {error, Reason} end, Result.

Actual work...: skvs_server.erl

ETS����������� ������������������  is����������� ������������������  a����������� ������������������  Key����������� ������������������  value����������� ������������������  store����������� ������������������  in����������� ������������������  RAM

Use cases

Gaming Industry

Gaming Industry

Messaging / IM

Messaging / IM

Payments

Payments

Databases

Databases

Others

Others

Some day...

Every highly interactive website? ;)

Every highly interactive website? ;)

Hi

Hey

HelloPayOuch!

!BufNO!

Would you...

Internet of things

And now what?

Install Erlang/OTP!

https://www.erlang-solutions.com/downloads/download-erlang-otp

Use a great IDE• IntelliJ + Erlang (plugin)

• Sublime Text + SublimErl

• Emacs

Read some books

RTFM

• http://www.erlang.org/doc.html

• http://erldocs.com/

Join mailing lists

• Official Erlang mailing list

• http://erlang.org/mailman/listinfo/erlang-questions

• Join Barcelona Erlang user group on google groups

Find know-how

• Check http://www.erlang-factory.com/ videos

• Search for Erlang conferences on slideshare

• Pray for an http://erlangcamp.com/ near your city

Read some code

This is the result of 6 months of fun learning Erlang/OTP

We are looking for awesome projects

http://es.linkedin.com/in/jllonch

http://es.linkedin.com/in/jvalduvieco

Thank you!

https://github.com/jvalduvieco/betabeers_201303

Thank you!

we����������� ������������������  hope����������� ������������������  you����������� ������������������  feel����������� ������������������  like����������� ������������������  him����������� ������������������  :)

(we����������� ������������������  did)

https://github.com/jvalduvieco/betabeers_201303

Erlang, The Movie

http://www.youtube.com/watch?v=uKfKtXYLG78

Images sourceshttp://diromero.wordpress.com/2011/10/07/home-automation/http://iffergan.com/http://technode.com/2012/05/14/internet-of-things-not-just-a-concept-for-fund-raising/http://modernherstory.wordpress.com/2011/05/18/open-minds-open-hearts/http://www.i-m.co/eviemouse/problemsolved/http://strategicsalesmarketingosmg.wordpress.com/2012/06/25/who-are-twitter-users/http://www.secureworks.com/it_security_services/advantage/soc/http://labourlist.org/2011/11/my-biggest-worry-about-labour%E2%80%99s-future/broken-chain/http://prothemedesign.com/how-to/why-you-should-keep-wordpress-and-your-plugins-up-to-date/attachment/matrix-code-update/http://thegapbetweentwoworlds.com/category/career-transitionhttp://www.wingweb.co.uk/Images/697/KC-10_Extender_SR-71_Blackbirdhttp://www.tonywoodtraining.com/2010/11/29/motivation-to-exercise-and-eat-right/http://portalmie.com/blog/6/2011/09/kushimoto-diving-park-tokushima-revista-no-7/http://www.bcsagroup.com/http://www.losemyaccent.com/tag/hand/http://articulo.mercadolibre.com.ar/MLA-450970296-cortaplumas-victorinox-huntsman-15-usos-navaja-origen-suizo-_JMhttp://openclipart.org/detail/4112/http://blog-en.coaching-go.com/2012/02/learn-to-say-no-and-know-how-to-say-yes/ok-2/http://en.wikipedia.org/wiki/File:We_Can_Do_It!.jpghttp://triniblog.wordpress.com/tag/laberintos/http://www.catskillsnyrealestate.com/Want-More-Info-Catskill-Real-Estate.phphttp://www.thelovelyplanet.net/lush-green-images-planet-earth/http://www.growthmax.com/how-exactly-does-growthmax-plus-make-you-grow-taller/http://www.ayurvedalive.in/keep-your-eyes-healthy-beautifulhttp://my.mmosite.com/510619/blog/item/lord_of_the_rings_online.htmlhttp://scifistorm.org/2010/03/24/lord-of-the-rings-blu-ray-review/http://www.123rf.com/photo_15612022_3d-cartoon-bug.htmlhttp://www.airliners.net/photo/1134244/L/http://www.muypymes.com/2009/12/04/moleskine-mucho-mas-que-una-agenda-personalhttp://learnyousomeerlang.com/the-hitchhikers-guide-to-concurrencyhttp://planetpooks.com/one-more-reason-to-love-hermiones-handbag/

top related