Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Erlang for Rubyists

Erlang for Rubyists

given at the vienna.rb october 2013 meetup

Martin Schürrer

October 11, 2013
Tweet

More Decks by Martin Schürrer

Other Decks in Programming

Transcript

  1. Erlang is a programming language used to build massively scalable

    soft real-time systems with requirements on high availability.
  2. Operating System Operating System BEAM stdlib OTP Rails MRI ERTS

    STDLIB kernel Erlang Elixir JavaScript CoffeeScript Ruby Erlang/OTP
  3. OS Process Erlang VM Erlang Node NOT Erlang Process Erlang

    Process Actor light-weight Thread NOT OS Process
  4. **********" **********" **********" **********" **********" **********" **********" **********" **********" **********"

    **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" **********" One$.NET$4.0$Thread$$ (allocates$one$megabyte)$ One$Erlang$Process$(allocates$one$kilobyte)$ *$ @bryan_hunter
  5. Heap Mailbox Stack Heap Mailbox Stack Heap Mailbox Stack Heap

    Mailbox Stack Heap Mailbox Stack Message Heap Mailbox Stack
  6. Mailbox Message 1 Message 2 Message 3 calculate something send

    message to P1 send message to P2 wait for incoming message calculate something send message to P1 wait for incoming message
  7. wait for incoming message handle message by sending more messages

    and then waiting for answers from other processes send an answer message back
  8. Who sends/receives messages? •other processes (obviously) •open files •open sockets

    •external programs (Ports) •Erlang VM notifications •a process you watched died •a remote node you watched died
  9. Who sends/receives messages? •open files •“write this” •“read 15 bytes”

    -> “here are 15 bytes” •open sockets •“write this” •“some bytes just arrived” •external programs (Ports) •STDOUT/STDIN/STDERR
  10. require  'actor' pong  =  nil ping  =  Actor.spawn  do  

     loop  do        count  =  Actor.receive        break  puts(count)  if  count  >  1000        pong  <<  (count  +  1)    end end pong  =  Actor.spawn  do    loop  do        count  =  Actor.receive        break  puts(count)  if  count  >  1000                ping  <<  (count  +  1)    end end ping  <<  1 sleep  1
  11. defmodule  PingPong  do    def  start  do      

     :ok  =  :proc_lib.start_link(__MODULE__,  :init,  [:ping,  :pong])        :ok  =  :proc_lib.start_link(__MODULE__,  :init,  [:pong,  :ping])        :ping  <-­‐  1    end      def  init(my_name,  other_name)  do        Process.register(self(),  my_name)        :proc_lib.init_ack(:ok)        loop(my_name,  other_name)    end      def  loop(my_name,  other_name)  do        receive  do            count  -­‐>                other_name  <-­‐  (count  +  1)                if  count  >  1000  do                    IO.puts("#{my_name}  #{count}")                else                    loop(my_name,  other_name)                end        end    end end
  12. -­‐module(pingpong). -­‐export([start/0,  init/2]).   start()  -­‐>    ok  =  proc_lib:start_link(?MODULE,

     init,  [ping,  pong]),    ok  =  proc_lib:start_link(?MODULE,  init,  [pong,  ping]),    ping  !  1.   init(MyName,  OtherName)  -­‐>    true  =  erlang:register(MyName,  self()),    proc_lib:init_ack(ok),    loop(MyName,  OtherName).   loop(MyName,  OtherName)  -­‐>    receive        Count  -­‐>            OtherName  !  (Count  +  1),            case  Count  >  1000  of                true  -­‐>                    io:fwrite("~p  ~p~n",  [MyName,  Count]);                false  -­‐>                    loop(MyName,  OtherName)            end    end.
  13. require  'actor' pong  =  nil ping  =  Actor.spawn  do  

     loop  do        count  =  Actor.receive        break  puts(count)  if  count  >  1000        pong  <<  (count  +  1)    end end pong  =  Actor.spawn  do    loop  do        count  =  Actor.receive        break  puts(count)  if  count  >  1000                ping  <<  (count  +  1)    end end ping  <<  1 sleep  1
  14. require  'actor' pong  =  nil ping  =  Actor.spawn  do  

     loop  do        count  =  Actor.receive        break  puts(count)  if  count  >  1000        pong  <<  (count  +  1)    end end pong  =  Actor.spawn  do    loop  do        count  =  Actor.receive        break  puts(count)  if  count  >  1000        BCrypt::Password.create('secret',  cost:  50)  #  <-­‐-­‐  oh  well        ping  <<  (count  +  1)    end end ping  <<  1 sleep  1
  15. 2000 reductions left: calculate(something) 1000 reductions left: still calculating(something) 0

    reductions left: suspend process run next process green threads = cheap context switching
  16. Conn 1 Conn 2 Conn 3 Conn 4 Conn 5

    Player 1 Player 2 Player 3 Player 4 Player 5 Table 1 Table 2 Game 1 Game 5
  17. Heap Mailbox Stack Heap Mailbox Stack Heap Mailbox Stack Heap

    Mailbox Stack Heap Mailbox Stack Heap Mailbox Stack