Ruby e Erlang
de mãos dadas

     Éverton Ribeiro
    nuxlli@gmail.com
Quem?
Quem?

• Desenvolvedor web
• Ex Administrador de redes
• Desenvolvedor e Pesquisador Abril
• http://nuxlli.com.br
• @nuxlli
O que queremos?

Criar uma arquitetura que junte as duas
  linguagens de forma que uma possa
   favorecer a outra e tentar eliminar
           suas deficiências.
Agenda

• Linguagens: Vantagens e
  Desvantagens
• Onde usamos
• Erlang distribuída
• Lib para facilitar a vida
• Futuro da lib
Erlang - Vantagens

• Suporte à concorrência (no threads)
• Hot Swapping Code nativo
• Distribuída
• Feita para ambientes Real Time
• Libs de alta performance
Erlang - Desvantagens

• Curva de aprendizado muito alta
  (paradigma funcional)
• Dificuldade para criação de
  framework web
• Code base complexo
• Poucos desenvolvedores
Ruby - Vantagens


• Curva de aprendizado baixa
• Menos é mais
• Comunidade de desenvolvedores
  grande
Ruby - Desvantagens


• Desempenho
• Pouca aceitação no mundo EE
• Complexidade para desenvolver
 aplicações distribuídas
O que elas ganham?
• Erlang
 • Produtividade
 • Facilidade em escrever testes
• Ruby
 • Performance
 • Programação distribuída
na prática - live
Mas antes
Programação distribuída
      com Erlang
• Clusters
• Todo interpretador rodando é um nó.
• Um nó confia plenamente no outro.
• rpc call
Exemplo
-module(math).
-export([start/0,add/2]).

start() ->
    register(?MODULE, spawn(fun() -> loop() end)).

add(X,Y) ->
    ?MODULE ! {self(), add, X, Y},
    receive
         {?MODULE, Response} -> Response
    end.

loop() ->
    receive
         {From, add, X, Y} ->
             Sum = X + Y,
             From ! {?MODULE,Sum},
             loop();
         Any ->
             loop()
    end.
Exemplo
                          Primeiro nó
$ erlc math.erl
$ erl -sname smath
(smath@localhost) 1> math:start().
true
(smath@localhost) 2> math:add(1, 2).
3




                           Segundo nó
$ erl -sname cmath
(cmath@localhost) 1> rpc:call(smath@localhost, math, add, [2, 3]).
4
voltando ao live
Como fizemos




EPMD (Erlang Port Mapper Daemon)
Problemas identificados:

• Fora do padrão Erlang
• Manutenção, 3 pontos de mudança:
 • Nós Erlang
 • Servidor Erlang (API HTTP)
 • Aplicação Ruby on Rails
Uma forma melhor




EPMD (Erlang Port Mapper Daemon)
Porque é melhor:


• É mantido o padrão Erlang
• Manutenção, 2 pontos de mudança:
 • Nós Erlangs
 • Aplicação Ruby on Rails
Mas como fazer?



    ?
rinterface

• http://github.com/nofxx/rinterface
• Lib de comunicação com nós erlang
• EPMD (Erlang Port Mapper Daemon)
• Criado por: Dave Bryson
• Contribuição: nofxx e nuxlli
Como funciona?
                 Em Erlang:

rpc:call(smath@localhost, math, add, [10, 20])


                 Em Ruby:

 Erlang::Node.rpc(:smath,:math,:add, [10,20])
Status:
• O que faz:
  • Chamadas rpc aos nós erlang
  • Tratamento de tipos: inteiros, flutuantes, atoms,
     tuplas, listas e strings

  • API simples para execução de chamadas
• O que queremos:
  • Comportar como um nó Erlang
  • Facilities para rodar testes
  • DSL para chamadas e respostas
Testes em Erlang
                        fib.erl
-module(fib).
-export([fib/1]).
-include_lib("eunit/include/eunit.hrl").

fib(0) -> 1;
fib(1) -> 1;
fib(N) when N > 1 -> fib(N-1) + fib(N-2).

fib_test_() ->
       [?_assert(fib(0) =:= 1),
        ?_assert(fib(1) =:= 1),
        ?_assert(fib(2) =:= 2),
        ?_assert(fib(3) =:= 3),
        ?_assert(fib(4) =:= 5),
        ?_assert(fib(5) =:= 8),
        ?_assertException(error, function_clause, fib(-1)),
        ?_assert(fib(31) =:= 2178309)].
Teste com rinterface
           (atualmente)
                            fib_spec.rb
require 'minitest/unit'
require 'minitest/spec'
require 'rinterface'
MiniTest::Unit.autorun

describe "Erlang Fib" do
  it "should " do
    assert_equal Erlang::Node.rpc(:sfib,   :fib,   :fib,   [0]), [:ok, 1]
    assert_equal Erlang::Node.rpc(:sfib,   :fib,   :fib,   [1]), [:ok, 1]
    assert_equal Erlang::Node.rpc(:sfib,   :fib,   :fib,   [3]), [:ok, 3]
    assert_equal Erlang::Node.rpc(:sfib,   :fib,   :fib,   [4]), [:ok, 5]
    assert_equal Erlang::Node.rpc(:sfib,   :fib,   :fib,   [5]), [:ok, 8]
    assert_equal Erlang::Node.rpc(:sfib,   :fib,   :fib,   [-1])[0], :badrpc
    assert_equal Erlang::Node.rpc(:sfib,   :fib,   :fib,   [31]), [:ok, 2178309]
  end
end
Teste com rinterface
                        fib_spec.rb
require 'minitest/unit'
require 'minitest/spec'
require 'rinterface/test'
MiniTest::Unit.autorun

describe "Erlang Fib" do
  before do
    FibMod = Erlang::Node.new(:sfib, :fib)
  end

  it "should " do
    assert_equal FibMod.fib(0), 1
    assert_equal FibMod.fib(1), 1
    assert_equal FibMod.fib(3), 3
    assert_equal FibMod.fib(4), 5
    assert_equal FibMod.fib(5), 8
    assert_equal FibMod.fib(31), 2178309
    assert_raises (Server::Badrpc) { assert_equal FibMod.fib(-1) }
  end
end
Futuro - Client Node

# Erlang::Node.new(:'node@localhost')
ServerFib = Erlang::Node.new(:sfib)
ServerFib.fib.fib(1) # 1

# Erlang::Node.new(:'node@localhost', :module)
ModFib = Erlang::Node.new(:sfib, :fib)
ModFib.fib(1) # 1
Futuro - Server Node

Erlang::Mod.new :math do
  def add x, y
    x + y
  end
end

module Fib
  def fib(n)
    n < 2 ? n : fib(n-1) + fib(n-2)
  end
end
Erlang::Mod.new :fib => Fib
Perguntas?


http://github.com/nofxx/rinterface
        http://nuxlli.com.br
           Éverton Ribeiro
          nuxlli@gmail.com

Ruby e Erlang de mãos dadas

  • 1.
    Ruby e Erlang demãos dadas Éverton Ribeiro nuxlli@gmail.com
  • 2.
  • 3.
    Quem? • Desenvolvedor web •Ex Administrador de redes • Desenvolvedor e Pesquisador Abril • http://nuxlli.com.br • @nuxlli
  • 4.
    O que queremos? Criaruma arquitetura que junte as duas linguagens de forma que uma possa favorecer a outra e tentar eliminar suas deficiências.
  • 5.
    Agenda • Linguagens: Vantagense Desvantagens • Onde usamos • Erlang distribuída • Lib para facilitar a vida • Futuro da lib
  • 7.
    Erlang - Vantagens •Suporte à concorrência (no threads) • Hot Swapping Code nativo • Distribuída • Feita para ambientes Real Time • Libs de alta performance
  • 8.
    Erlang - Desvantagens •Curva de aprendizado muito alta (paradigma funcional) • Dificuldade para criação de framework web • Code base complexo • Poucos desenvolvedores
  • 10.
    Ruby - Vantagens •Curva de aprendizado baixa • Menos é mais • Comunidade de desenvolvedores grande
  • 11.
    Ruby - Desvantagens •Desempenho • Pouca aceitação no mundo EE • Complexidade para desenvolver aplicações distribuídas
  • 12.
    O que elasganham? • Erlang • Produtividade • Facilidade em escrever testes • Ruby • Performance • Programação distribuída
  • 13.
  • 14.
  • 15.
    Programação distribuída com Erlang • Clusters • Todo interpretador rodando é um nó. • Um nó confia plenamente no outro. • rpc call
  • 16.
    Exemplo -module(math). -export([start/0,add/2]). start() -> register(?MODULE, spawn(fun() -> loop() end)). add(X,Y) -> ?MODULE ! {self(), add, X, Y}, receive {?MODULE, Response} -> Response end. loop() -> receive {From, add, X, Y} -> Sum = X + Y, From ! {?MODULE,Sum}, loop(); Any -> loop() end.
  • 17.
    Exemplo Primeiro nó $ erlc math.erl $ erl -sname smath (smath@localhost) 1> math:start(). true (smath@localhost) 2> math:add(1, 2). 3 Segundo nó $ erl -sname cmath (cmath@localhost) 1> rpc:call(smath@localhost, math, add, [2, 3]). 4
  • 18.
  • 19.
    Como fizemos EPMD (ErlangPort Mapper Daemon)
  • 20.
    Problemas identificados: • Forado padrão Erlang • Manutenção, 3 pontos de mudança: • Nós Erlang • Servidor Erlang (API HTTP) • Aplicação Ruby on Rails
  • 21.
    Uma forma melhor EPMD(Erlang Port Mapper Daemon)
  • 22.
    Porque é melhor: •É mantido o padrão Erlang • Manutenção, 2 pontos de mudança: • Nós Erlangs • Aplicação Ruby on Rails
  • 23.
  • 24.
    rinterface • http://github.com/nofxx/rinterface • Libde comunicação com nós erlang • EPMD (Erlang Port Mapper Daemon) • Criado por: Dave Bryson • Contribuição: nofxx e nuxlli
  • 25.
    Como funciona? Em Erlang: rpc:call(smath@localhost, math, add, [10, 20]) Em Ruby: Erlang::Node.rpc(:smath,:math,:add, [10,20])
  • 26.
    Status: • O quefaz: • Chamadas rpc aos nós erlang • Tratamento de tipos: inteiros, flutuantes, atoms, tuplas, listas e strings • API simples para execução de chamadas • O que queremos: • Comportar como um nó Erlang • Facilities para rodar testes • DSL para chamadas e respostas
  • 27.
    Testes em Erlang fib.erl -module(fib). -export([fib/1]). -include_lib("eunit/include/eunit.hrl"). fib(0) -> 1; fib(1) -> 1; fib(N) when N > 1 -> fib(N-1) + fib(N-2). fib_test_() -> [?_assert(fib(0) =:= 1), ?_assert(fib(1) =:= 1), ?_assert(fib(2) =:= 2), ?_assert(fib(3) =:= 3), ?_assert(fib(4) =:= 5), ?_assert(fib(5) =:= 8), ?_assertException(error, function_clause, fib(-1)), ?_assert(fib(31) =:= 2178309)].
  • 28.
    Teste com rinterface (atualmente) fib_spec.rb require 'minitest/unit' require 'minitest/spec' require 'rinterface' MiniTest::Unit.autorun describe "Erlang Fib" do it "should " do assert_equal Erlang::Node.rpc(:sfib, :fib, :fib, [0]), [:ok, 1] assert_equal Erlang::Node.rpc(:sfib, :fib, :fib, [1]), [:ok, 1] assert_equal Erlang::Node.rpc(:sfib, :fib, :fib, [3]), [:ok, 3] assert_equal Erlang::Node.rpc(:sfib, :fib, :fib, [4]), [:ok, 5] assert_equal Erlang::Node.rpc(:sfib, :fib, :fib, [5]), [:ok, 8] assert_equal Erlang::Node.rpc(:sfib, :fib, :fib, [-1])[0], :badrpc assert_equal Erlang::Node.rpc(:sfib, :fib, :fib, [31]), [:ok, 2178309] end end
  • 29.
    Teste com rinterface fib_spec.rb require 'minitest/unit' require 'minitest/spec' require 'rinterface/test' MiniTest::Unit.autorun describe "Erlang Fib" do before do FibMod = Erlang::Node.new(:sfib, :fib) end it "should " do assert_equal FibMod.fib(0), 1 assert_equal FibMod.fib(1), 1 assert_equal FibMod.fib(3), 3 assert_equal FibMod.fib(4), 5 assert_equal FibMod.fib(5), 8 assert_equal FibMod.fib(31), 2178309 assert_raises (Server::Badrpc) { assert_equal FibMod.fib(-1) } end end
  • 30.
    Futuro - ClientNode # Erlang::Node.new(:'node@localhost') ServerFib = Erlang::Node.new(:sfib) ServerFib.fib.fib(1) # 1 # Erlang::Node.new(:'node@localhost', :module) ModFib = Erlang::Node.new(:sfib, :fib) ModFib.fib(1) # 1
  • 31.
    Futuro - ServerNode Erlang::Mod.new :math do def add x, y x + y end end module Fib def fib(n) n < 2 ? n : fib(n-1) + fib(n-2) end end Erlang::Mod.new :fib => Fib
  • 32.
    Perguntas? http://github.com/nofxx/rinterface http://nuxlli.com.br Éverton Ribeiro nuxlli@gmail.com