SlideShare a Scribd company logo
EVERYBODY POLYGLOT!
(Cross-Language RPC with Erlang)


   ErlangDC · December 2011


       Rusty Klophaus - @rustyio
          Basho Technologies
Languages have Strengths




     http://wordaligned.org/articles/distorted-software




                             2                            @rustyio
Connections are Hard
            Serialization
      Versioning & Upgrades
      Data Type Mismatches
Speed, Bottlenecks & Back-Pressure
        Inadequate Tooling
        Context Switching




                3                    @rustyio
Connections are Hard




   http://wordaligned.org/articles/distorted-software




                           4                            @rustyio
This Talk
Create An Example Service
 Any service will do, just need a framework for discussion.

Expose Application via Interfaces
 • REST / JSON via Webmachine & Spooky
 • Protocol Buffers via erlang-protobuffs
 • BERT-RPC via Ernie Server

Code
 http://github.com/rustyio/ErlangRPCDemo



                                  5                           @rustyio
This Talk
Our Application: A Sequence Server
 Erlang service that returns a sequence of numbers.

    1   sequence(N) ->
    2       List1 = lists:seq(1, N),
    3       List2 = [list_to_binary(integer_to_list(X)) || X <- List1],
    4       {ok, List2};
    5
    6   %% sequence(2).
    7   {ok, [<<"1">>, <<"2">>]}.
    8
    9   %% sequence(5).
   10   {ok, [<<"1">>, <<"2">>, <<"3">>, <<"4">>, <<"5">>]}.
   11
   12   %% sequence(50000).
   13   {ok, [<<"1">>, <<"2">>, <<"3">>, <<"4">>, ...]}.


                                     6                                    @rustyio
Overview
     REST?
Protocol Buffers?
  BERT-RPC?




        7           @rustyio
REST / JSON - Overview
REST - Representational State Transfer
 Convention for talking to applications over HTTP
 Actions are Verbs are HTTP Methods (GET/PUT/POST/DELETE/...)
 Objects are nouns are URLs
  GET /users/5

JSON - Javascript Object Notation
 Encode data as parseable Javascript
 Understood by everything
 Human Readable
  {"id":5,"first":"Rusty","last":"Klophaus"}

                                  8                             @rustyio
REST / JSON - Strengths & Weaknesses
Strengths
 Simple, easy to poke around
 Good support in every language
 Composable - Caches, Reverse Proxies, Load Balancers

Weaknesses
 General == More Handshaking/Metadata == More Overhead




                                9                        @rustyio
Protocol Buffers - Overview
Protocol Buffers
 Developed by Google
 It’s not a protocol, it’s a format:
 • You provide the client / server logic
 • Useful for transmission AND storage
 Define data structures in .proto file, generate code



 http://code.google.com/apis/protocolbuffers/
 https://github.com/ngerakines/erlang_protobuffs


                                10                    @rustyio
Protocol Buffers - Strengths & Weaknesses
Strengths
 Compact
 Add fields without breaking existing applications
 • Versioning is not strict

Weaknesses
 Configuration file (.proto) with new syntax to learn
 Generated code
 Uneven language support




                                 11                   @rustyio
BERT-RPC - Overview
BERT-RPC
 Developed by GitHub (Tom Preston-Werner)
 BERT = Binary Erlang Term
 • Encoding mimics native Erlang serialization
 http://bert-rpc.org
 https://github.com/mojombo/ernie

     1   % Request
     2   {call, ernie_sequence, sequence, [3]}
     3
     4   % Response
     5   {response, {ok, [<<"1">>, <<"2">>, <<"3">>]}}



                                   12                    @rustyio
BERT-RPC - Strengths & Weaknesses
Strengths
 Easy to set up
 Agile
 Compact

Weaknesses
 Uneven language support
 Less buzz than it deserves
 Not fully product-ized




                              13    @rustyio
Requests & Responses
What does the chatter look like?




               14                  @rustyio
REST / JSON - Request & Response
Request
 GET /sequence/3 HTTP/1.1
 User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4
 OpenSSL/0.9.8r zlib/1.2.5
 Host: localhost:8001
 Accept: */*


Response
 HTTP/1.1 200 OK
 Server: MochiWeb/1.1 WebMachine/1.9.0 (someone had painted it blue)
 Date: Wed, 23 Nov 2011 22:09:13 GMT
 Content-Type: application/json
 Content-Length: 21

 ["1","2","3"]
                                 15                                @rustyio
Protocol Buffers - Encoding
rpc_demo.proto
  1   message SequenceRequest {
  2       required uint32 n = 1;
  3   }
  4
  5   message SequenceResponse {
  6       repeated bytes sequence = 1;
  7   }




                                   16    @rustyio
Protocol Buffers - RPC
Request
   1 rpc_demo_pb:encode({sequencerequest, 3}).
   2 <<8,3>>


Response
   1 rpc_demo_pb:encode({sequenceresponse, [<<"1">>, <<"2">>, <<"3">>]}).
   2 <<10,1,49,10,1,50,10,1,51>>




                                   17                                  @rustyio
BERT-RPC - Encoding
1   term_to_binary([<<"1">>,<<"2">>,<<"3">>]).
2   <<131,108,0,0,0,3,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,1,51,106>>
3
4
5   bert:encode([<<"1">>,<<"2">>,<<"3">>]).
6   <<131,108,0,0,0,3,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,1,51,106>>




                                  18                                @rustyio
BERT-RPC - Encoding
 1   term_to_binary([<<"1">>,<<"2">>,<<"3">>]).
 2   <<131,108,0,0,0,3,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,1,51,106>>
 3
 4
 5   bert:encode([<<"1">>,<<"2">>,<<"3">>]).
 6   <<131,108,0,0,0,3,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,1,51,106>>
 7      |   |        | |          | |
 8      |   |        | |          | + Ascii value for '1'
 9      |   |        | |          + Length of string (1)
10      |   |        | + Next term is a string
11      |   |        + Length of list (3)
12      |   + Next term is a list
13      + Start of Erlang term




                                   19                                @rustyio
BERT-RPC - RPC
Request
   1 bert:encode({call, ernie_sequence, sequence, [5]}).

   3 <<131,104,4,100,0,4,99,97,108,108,100,0,14,101,114,110,
   4   105,101,95,115,101,113,117,101,110,99,101,100,0,8,115,
   5   101,113,117,101,110,99,101,107,0,1,5>>


Response
   1 bert:encode({reply,{ok,[<<"1">>,<<"2">>,<<"3">>,<<"4">>,<<"5">>]}}).
   2
   3 <<131,104,2,100,0,5,114,101,112,108,121,104,2,100,0,2,111,
   4   107,108,0,0,0,5,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,
   5   1,51,109,0,0,0,1,52,109,0,0,0,1,53,106>>




                                   20                                  @rustyio
Show me the Client Code!




           21              @rustyio
REST / JSON - Clients
CURL
       curl http://localhost:8001/sequence/5



Ruby Client
  1    url = "http://localhost:8001/sequence/5"
  2    resp = Net::HTTP.get_response(URI.parse(url))
  3    sequence = JSON.parse(resp.body)




                              22                       @rustyio
Protocol Buffers - Client
Ruby Client
  1   require 'beefcake'
  2
  3   class SequenceRequest
  4     include Beefcake::Message
  5     required :n, :int32, 1
  6   end
  7
  8   class SequenceResponse
  9     include Beefcake::Message
 10     repeated :sequence, :string, 1
 11   end
 12
 13   req = SequenceRequest.new(:n => 5)
 14   Socket.tcp("localhost", 8003) do |socket|
 15     socket.write(req.encode)
 16     m = socket.read
 17     return SequenceResponse.decode(m)
 18   end
                                     23           @rustyio
BERT-RPC - Client
Ruby Client
  1 require 'bert-rpc'
  2
  3 svc = BERTRPC::Service.new('localhost', 9999)
  4 sequence = svc.call.ernie_sequence.sequence(5)




                             24                      @rustyio
Show me the Server Code!




           25              @rustyio
REST / JSON - Server
Spooky Server
   1   -module(spooky_sequence).
   2   -behaviour(spooky).
   3   -export([init/1, get/2]).
   4
   5   init([])->
   6       [{port, 8002}].
   7
   8   get(_Req, ["sequence", Num])->
   9       case sequence:sequence(Num) of
  10            {ok, List} ->
  11                {200, mochijson2:encode(List)};
  12            {error, Error} ->
  13                {500, io_lib:format("~w", [Error])}
  14       end;
  15   get(_Req, _)->
  16       {400, "Usage: /sequence/:Num:"}.


                                    26                    @rustyio
REST / JSON - Server
Webmachine Server
   1   -module(webmachine_sequence).
   2   -export([init/1, content_types_provided/2, to_json/2]).
   3   -include_lib("webmachine/include/webmachine.hrl").
   4
   5   -record(ctx, { list }).
   6
   7   init([]) ->
   8       {ok, #ctx {}}.
   9
  10   content_types_provided(RD, Ctx) ->
  11       Types = [{"application/json", to_json}],
  12       {Types, RD, Ctx}.
  13
  14   to_json(RD, Ctx) ->
  15       {ok, List} = sequence:sequence(N),
  16       Body = mochijson2:encode(List),
  17       {Body, RD, Ctx}.
                                   27                            @rustyio
Protocol Buffers - Server
Erlang Server
   1   %% Erlang RPC Demo
                                                                                       57   handle_info({tcp, _Sock, _Data}, State) ->
   2   %% Copyright (c) 2011 Rusty Klophaus (@rustyio)
                                                                                       58       %% req =/= undefined: received a new request while another was in
   3   %% See MIT-LICENSE for licensing information.
                                                                                       59       %% progress -> Error
   4
                                                                                       60       lager:error("Received a new PB socket request"
   5   -module(protobuff_server).
                                                                                       61                   " while another was in progress"),
   6   -behaviour(gen_server).
                                                                                       62       {stop, normal, State};
   7
                                                                                       63
   8   -export([
                                                                                       64   handle_info(_, State) -> % Ignore any late replies from gen_servers/messages from fsms
   9            start_link/0,
                                                                                       65       {noreply, State}.
  10            set_socket/2,
                                                                                       66
  11            init/1,
                                                                                       67   terminate(_Reason, _State) ->
  12            handle_call/3,
                                                                                       68       ok.
  13            handle_cast/2,
                                                                                       69
  14            handle_info/2,
                                                                                       70   code_change(_OldVsn, State, _Extra) -> {ok, State}.
  15            terminate/2,
                                                                                       71
  16            code_change/3,
                                                                                       72   %% ===================================================================
  17            encode/1,
                                                                                       73   %% Handle PB Messages
  18            decode/1]).
                                                                                       74   %% ===================================================================
  19
                                                                                       75
  20   -record(state, { sock }).
                                                                                       76   process_message(#sequencerequest { n = N }, State) ->
  21
                                                                                       77       case sequence:sequence(N) of
  22   -include("rpc_demo_pb.hrl").
                                                                                       78            {ok, List} ->
  23
                                                                                       79                Resp = #sequenceresponse { sequence = List },
  24   %% ===================================================================
                                                                                       80                send_msg(Resp, State);
  25   %% Public API
                                                                                       81            {error, Reason} ->
  26   %% ===================================================================
                                                                                       82                Msg = io_lib:format("~w", [Reason]),
  27
                                                                                       83                Resp = #sequenceerror { message=Msg },
  28   start_link() ->
                                                                                       84                send_msg(Resp, State)
  29       gen_server:start_link(?MODULE, [], []).
                                                                                       85       end.
  30
                                                                                       86
  31   set_socket(Pid, Socket) ->
                                                                                       87   %% Send a message to the client
  32       gen_server:call(Pid, {set_socket, Socket}).
                                                                                       88   send_msg(Msg, State) ->
  33
                                                                                       89       Pkt = encode(Msg),
  34   init([]) ->
                                                                                       90       gen_tcp:send(State#state.sock, Pkt),
  35       {ok, #state{}}.
                                                                                       91       State.
  36
                                                                                       92
  37   handle_call({set_socket, Socket}, _From, State) ->
                                                                                       93   encode(Msg) ->
  38       inet:setopts(Socket, [{active, once}, {packet, 4}, {header, 1}]),
                                                                                       94       MsgType = element(1, Msg),
  39       {reply, ok, State#state{sock = Socket}}.
                                                                                       95       [msg_code(Msg) | rpc_demo_pb:iolist(MsgType, Msg)].
  40
                                                                                       96
  41   handle_cast(_Msg, State) ->
                                                                                       97   decode([MsgCode|MsgData]) ->
  42       {noreply, State}.
                                                                                       98       MsgType = msg_type(MsgCode),
  43
                                                                                       99       rpc_demo_pb:decode(MsgType, MsgData).
  44   handle_info({tcp_closed, Socket}, State=#state{sock=Socket}) ->
                                                                                      100
  45       {stop, normal, State};
                                                                                      101   msg_code(#sequencerequest {}) -> 1;
  46   handle_info({tcp_error, Socket, _Reason}, State=#state{sock=Socket}) ->
                                                                                      102   msg_code(#sequenceresponse {}) -> 2;
  47       {stop, normal, State};
                                                                                      103   msg_code(#sequenceerror {})    -> 3;
  48   handle_info({tcp, _Sock, MsgData}, State=#state{sock=Socket}) ->
                                                                                      104   msg_code(Other) ->
  49       Msg = decode(MsgData),
                                                                                      105       throw({unknown_pb_type, Other}).
  50       case process_message(Msg, State) of
                                                                                      106
  51            {pause, NewState} ->
                                                                                      107   msg_type(1) -> sequencerequest;
  52                ok;
                                                                                      108   msg_type(2) -> sequenceresponse;
  53            NewState ->
                                                                                      109   msg_type(3) -> sequenceerror;
  54                inet:setopts(Socket, [{active, once}])
                                                                                      110   msg_type(Other) ->
  55       end,
                                                                                      111       throw({unknown_pb_code, Other}).
  56       {noreply, NewState};


                                                                                 28                                                                                                  @rustyio
BERT-RPC - Server
Ernie Server - Erlang BERT-RPC Server
  1 %% FILE: ernie.config
  2 [
  3     {module, ernie_sequence},
  4     {type, native},
  5     {codepaths, []}
  6 ].

  1 -module(ernie_sequence).
  2 -export([sequence/1]).
  3
  4 sequence(N) ->
  5     sequence:sequence(N).


                                29      @rustyio
Benchmarks
How fast is it?




      30          @rustyio
Benchmarks
Disclaimers
 Benchmarking is hard
 The shape of your data matters (size and complexity)
 Speed is not the only objective




                                31                      @rustyio
Benchmarks:
Encoding Speed




      32         @rustyio
Encoding Speed - 5 items


       BERT      JSON      PB




                   33           @rustyio
Encoding Speed - 50 items


       BERT      JSON       PB




                   34            @rustyio
Encoding Speed - 500 items


       BERT      JSON        PB




                   35             @rustyio
Encoding Speed - 5,000 items


       BERT      JSON          PB




                   36               @rustyio
Encoding Speed - 50,000 items


        BERT                  JSON




           Sad Protocol Buffers :(


                     37              @rustyio
Encoding Speed - Ruby




         |       5 |      50 |     500 |     5,000
    -----+---------+---------+---------+----------
    JSON | 0.03 ms | 0.77 ms | 0.47 ms |   4.21 ms
      PB | 0.07 ms | 0.60 ms | 7.37 ms | 197.24 ms
    BERT | 0.08 ms | 0.52 ms | 4.97 ms | 52.42 ms




                          38                         @rustyio
Encoding Speed
Interpretations
 BERT wins in Erlang, because it’s native.
 JSON wins in Ruby.
 Protocol Buffers is slow all around for complex data.
 • Note: This is different from large data.




                                  39                     @rustyio
Benchmarks:
                     Single Hop


$ ping dell.local

PING dell.local (192.168.2.2): 56 data bytes
64 bytes from 192.168.2.2: icmp_seq=0 ttl=64 time=0.490 ms




                             40                              @rustyio
Benchmarks
More Disclaimers
 First approach exhausted TCP connections
 “Fixed” by tunneling connections, which impacts results




                                 41                        @rustyio
Operation Performance - 5 items


    BERT   PB   PB   SPOOKY   WEBMACHINE




                     42                    @rustyio
Operation Performance - 50 items


    BERT   PB   PB   SPOOKY   WEBMACHINE




                     43                    @rustyio
Operation Performance - 500 items


    BERT   PB   PB   SPOOKY   WEBMACHINE




                     44                    @rustyio
Operation Performance - 5,000 items


    BERT   PB   PB   SPOOKY   WEBMACHINE




                     45                    @rustyio
Encoding Speed
Interpretations
 Performance is fairly even for simple data.
 PB is clear loser for data with lots of items.
 Webmachine pays a tax for considering entire HTTP decision tree.

 Take these with a grain of salt, everything is tunneled over SSH.




                                   46                                @rustyio
Webmachine - HTTP Decision Tree




              47                  @rustyio
Benchmarks:
                   Multiple Hops


$ ping rusty.io

PING rusty.io (173.203.217.46): 56 data bytes
64 bytes from 173.203.217.46: icmp_seq=0 ttl=53 time=49.550 ms




                             48                             @rustyio
Operation Performance - 5 items


    BERT   PB   PB   SPOOKY   WEBMACHINE




                     49                    @rustyio
Operation Performance - 50 items


    BERT   PB   PB   SPOOKY   WEBMACHINE




                     50                    @rustyio
Operation Performance - 500 items


    BERT   PB   PB   SPOOKY   WEBMACHINE




                     51                    @rustyio
Operation Performance - 5,000 items


    BERT   PB   PB   SPOOKY   WEBMACHINE




                     52                    @rustyio
Operation Performance - Multiple Hops
Interpretations
 No clear winner.
 Network speed / variability is the bottleneck.

 Take these with a grain of salt, everything is tunneled over SSH.




                                   53                                @rustyio
The Results
Recommendations
 Start with REST / JSON
 Optimize for performance with Protocol Buffers
 Get adventurous with BERT-RPC
 • Easy to set up == Easy to back out

Get Involved!
 Protocol Buffers NIF?
 JSON NIF?
 General Ernie (BERT-RPC) improvements:
 • Re-use connections, better packaging & documentation

                               54                         @rustyio
Honorable Mentions
Other RPC Frameworks:
  Thrift - http://thrift.apache.org/ (Originally Facebook)
  Avro - http://avro.apache.org/docs/current/
  XML-RPC
  CORBA - http://www.erlang.org/doc/man/corba.html
  UBF - http://www.sics.se/~joe/ubf/site/home.html
  MsgPack - http://msgpack.org/
  Etch - http://incubator.apache.org/projects/etch.html
  ASN.1 - http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One

Erlang <-> Other Code:
  Erlang "ports" - integration via stdin/stdout.
  Bifs - Extend Erlang with new functions.

"Fake" Erlang Nodes:
  JInterface (it is... not great)
  C Nodes - http://www.erlang.org/doc/tutorial/cnode.html

                                                             55       @rustyio
Related Talks
• Anton Lavrik - Piqi-RPC: exposing Erlang services via JSON, XML and Google
  Protocol Buffers over HTTP
  http://www.erlang-factory.com/conference/SFBay2011/speakers/AntonLavrik
• Tom Preston-Werner - BERT is to Erlang as JSON is to JavaScript
  http://www.erlang-factory.com/conference/ErlangUserConference2009/speakers/
  TomPrestonWerner
• Todd Lipcon - Thrift Avro/Erlang Bindings
  http://www.erlang-factory.com/conference/SFBay2010/speakers/toddlipcon
• Cliff Moon - Building Polyglot Distributed Systems with Jinterface
  http://www.erlang-factory.com/conference/SFBay2011/speakers/CliffMoon
• Kresten Krab Thorup - Erjang - A JVM-based Erlang VM
  http://www.erlang-factory.com/conference/SFBay2010/speakers/
  KrestenKrabThorup
• Yurii Rashkovskii - Beam.JS: Erlang meets JavaScript
  http://www.erlang-factory.com/conference/SFBay2011/speakers/YuriiRashkovskii

                                      56                                        @rustyio
Thanks!
Questions?




    57       @rustyio

More Related Content

What's hot

Defcamp 2013 - SSL Ripper
Defcamp 2013 - SSL RipperDefcamp 2013 - SSL Ripper
Defcamp 2013 - SSL Ripper
DefCamp
 
us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-La...
us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-La...us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-La...
us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-La...
sonjeku1
 

What's hot (20)

Rbootcamp Day 5
Rbootcamp Day 5Rbootcamp Day 5
Rbootcamp Day 5
 
Udp socket programming(Florian)
Udp socket programming(Florian)Udp socket programming(Florian)
Udp socket programming(Florian)
 
API Design Workshop
API Design WorkshopAPI Design Workshop
API Design Workshop
 
Writing and using php streams and sockets
Writing and using php streams and socketsWriting and using php streams and sockets
Writing and using php streams and sockets
 
Defcamp 2013 - SSL Ripper
Defcamp 2013 - SSL RipperDefcamp 2013 - SSL Ripper
Defcamp 2013 - SSL Ripper
 
us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-La...
us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-La...us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-La...
us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-La...
 
Network sockets
Network socketsNetwork sockets
Network sockets
 
Efficient System Monitoring in Cloud Native Environments
Efficient System Monitoring in Cloud Native EnvironmentsEfficient System Monitoring in Cloud Native Environments
Efficient System Monitoring in Cloud Native Environments
 
Raspberry pi Part 23
Raspberry pi Part 23Raspberry pi Part 23
Raspberry pi Part 23
 
101 3.1 gnu and unix commands v4
101 3.1 gnu and unix commands v4101 3.1 gnu and unix commands v4
101 3.1 gnu and unix commands v4
 
3.1 gnu and unix commands v4
3.1 gnu and unix commands v43.1 gnu and unix commands v4
3.1 gnu and unix commands v4
 
Debugging of (C)Python applications
Debugging of (C)Python applicationsDebugging of (C)Python applications
Debugging of (C)Python applications
 
101 3.4 use streams, pipes and redirects v2
101 3.4 use streams, pipes and redirects v2101 3.4 use streams, pipes and redirects v2
101 3.4 use streams, pipes and redirects v2
 
JavaOne 2009 - TS-5276 - RESTful Protocol Buffers
JavaOne 2009 - TS-5276 - RESTful  Protocol BuffersJavaOne 2009 - TS-5276 - RESTful  Protocol Buffers
JavaOne 2009 - TS-5276 - RESTful Protocol Buffers
 
Modern javascript localization with c-3po and the good old gettext
Modern javascript localization with c-3po and the good old gettextModern javascript localization with c-3po and the good old gettext
Modern javascript localization with c-3po and the good old gettext
 
Network commands
Network commandsNetwork commands
Network commands
 
Log Visualization - Bellua BCS 2006
Log Visualization - Bellua BCS 2006Log Visualization - Bellua BCS 2006
Log Visualization - Bellua BCS 2006
 
Debug Line Issues After Relaxation.
Debug Line Issues After Relaxation.Debug Line Issues After Relaxation.
Debug Line Issues After Relaxation.
 
03 - Refresher on buffer overflow in the old days
03 - Refresher on buffer overflow in the old days03 - Refresher on buffer overflow in the old days
03 - Refresher on buffer overflow in the old days
 
ZendCon 08 php 5.3
ZendCon 08 php 5.3ZendCon 08 php 5.3
ZendCon 08 php 5.3
 

Viewers also liked

Ch2 2014 Kristen Ricker Nixa High School
Ch2 2014 Kristen Ricker Nixa High School Ch2 2014 Kristen Ricker Nixa High School
Ch2 2014 Kristen Ricker Nixa High School
rickerkristen
 
Book4 unit1-lesson5
Book4 unit1-lesson5Book4 unit1-lesson5
Book4 unit1-lesson5
stthomas8
 
Beautiful Women Of China
Beautiful Women Of ChinaBeautiful Women Of China
Beautiful Women Of China
Ren
 
Filtros de cabine
Filtros de cabineFiltros de cabine
Filtros de cabine
tuliovmg1
 
阳光保险,摇一摇流程
阳光保险,摇一摇流程阳光保险,摇一摇流程
阳光保险,摇一摇流程
朋 陈
 
The quality of work and health inequalities – cross-national differences
The quality of work and health inequalities –  cross-national differences �The quality of work and health inequalities –  cross-national differences �
The quality of work and health inequalities – cross-national differences
sophieproject
 
2012 06 FGV Custo Mão de Obra Encargos Sociai Brasil
2012 06   FGV Custo Mão de Obra Encargos Sociai Brasil2012 06   FGV Custo Mão de Obra Encargos Sociai Brasil
2012 06 FGV Custo Mão de Obra Encargos Sociai Brasil
Siamfesp Sindicato
 
Ea conference st albert feb 2014
Ea conference  st albert feb 2014Ea conference  st albert feb 2014
Ea conference st albert feb 2014
tobylscott
 

Viewers also liked (20)

Ch2 2014 Kristen Ricker Nixa High School
Ch2 2014 Kristen Ricker Nixa High School Ch2 2014 Kristen Ricker Nixa High School
Ch2 2014 Kristen Ricker Nixa High School
 
Book4 unit1-lesson5
Book4 unit1-lesson5Book4 unit1-lesson5
Book4 unit1-lesson5
 
Beautiful Women Of China
Beautiful Women Of ChinaBeautiful Women Of China
Beautiful Women Of China
 
Inside sina weibo
Inside sina weiboInside sina weibo
Inside sina weibo
 
Creating the Startup The Accounting Panorama
Creating the Startup The Accounting PanoramaCreating the Startup The Accounting Panorama
Creating the Startup The Accounting Panorama
 
Say little, do more.
Say little, do more.Say little, do more.
Say little, do more.
 
Poor Pigs
Poor PigsPoor Pigs
Poor Pigs
 
Que es google docs
Que es google docsQue es google docs
Que es google docs
 
Miquel Martí i Pol
Miquel Martí i PolMiquel Martí i Pol
Miquel Martí i Pol
 
Presentation6
Presentation6Presentation6
Presentation6
 
Visual Network Analysis
Visual Network AnalysisVisual Network Analysis
Visual Network Analysis
 
Filtros de cabine
Filtros de cabineFiltros de cabine
Filtros de cabine
 
Synapseindia android apps (operating system)
Synapseindia android apps (operating system)Synapseindia android apps (operating system)
Synapseindia android apps (operating system)
 
Yg Ini 1
Yg Ini 1Yg Ini 1
Yg Ini 1
 
阳光保险,摇一摇流程
阳光保险,摇一摇流程阳光保险,摇一摇流程
阳光保险,摇一摇流程
 
The quality of work and health inequalities – cross-national differences
The quality of work and health inequalities –  cross-national differences �The quality of work and health inequalities –  cross-national differences �
The quality of work and health inequalities – cross-national differences
 
2012 06 FGV Custo Mão de Obra Encargos Sociai Brasil
2012 06   FGV Custo Mão de Obra Encargos Sociai Brasil2012 06   FGV Custo Mão de Obra Encargos Sociai Brasil
2012 06 FGV Custo Mão de Obra Encargos Sociai Brasil
 
33 Period week
33 Period week33 Period week
33 Period week
 
Global and china obd telematics industry report, 2014 2015
Global and china obd telematics industry report, 2014 2015Global and china obd telematics industry report, 2014 2015
Global and china obd telematics industry report, 2014 2015
 
Ea conference st albert feb 2014
Ea conference  st albert feb 2014Ea conference  st albert feb 2014
Ea conference st albert feb 2014
 

Similar to Everybody Polyglot! - Cross-Language RPC with Erlang

Use perl creating web services with xml rpc
Use perl creating web services with xml rpcUse perl creating web services with xml rpc
Use perl creating web services with xml rpc
Johnny Pork
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operations
grim_radical
 
H2O World - What's New in H2O with Cliff Click
H2O World - What's New in H2O with Cliff ClickH2O World - What's New in H2O with Cliff Click
H2O World - What's New in H2O with Cliff Click
Sri Ambati
 

Similar to Everybody Polyglot! - Cross-Language RPC with Erlang (20)

Relayd: a load balancer for OpenBSD
Relayd: a load balancer for OpenBSD Relayd: a load balancer for OpenBSD
Relayd: a load balancer for OpenBSD
 
Use perl creating web services with xml rpc
Use perl creating web services with xml rpcUse perl creating web services with xml rpc
Use perl creating web services with xml rpc
 
CocoaConf: The Language of Mobile Software is APIs
CocoaConf: The Language of Mobile Software is APIsCocoaConf: The Language of Mobile Software is APIs
CocoaConf: The Language of Mobile Software is APIs
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 Version
 
Valerii Vasylkov Erlang. measurements and benefits.
Valerii Vasylkov Erlang. measurements and benefits.Valerii Vasylkov Erlang. measurements and benefits.
Valerii Vasylkov Erlang. measurements and benefits.
 
SE2016 Exotic Valerii Vasylkov "Erlang. Measurements and benefits"
SE2016 Exotic Valerii Vasylkov "Erlang. Measurements and benefits"SE2016 Exotic Valerii Vasylkov "Erlang. Measurements and benefits"
SE2016 Exotic Valerii Vasylkov "Erlang. Measurements and benefits"
 
abu.rpc intro
abu.rpc introabu.rpc intro
abu.rpc intro
 
Red Hat Forum Tokyo - OpenStack Architecture
Red Hat Forum Tokyo - OpenStack ArchitectureRed Hat Forum Tokyo - OpenStack Architecture
Red Hat Forum Tokyo - OpenStack Architecture
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
Pycon - Python for ethical hackers
Pycon - Python for ethical hackers Pycon - Python for ethical hackers
Pycon - Python for ethical hackers
 
Non-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.jsNon-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.js
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operations
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Postgres Vienna DB Meetup 2014
Postgres Vienna DB Meetup 2014Postgres Vienna DB Meetup 2014
Postgres Vienna DB Meetup 2014
 
Getting started with RDO Havana
Getting started with RDO HavanaGetting started with RDO Havana
Getting started with RDO Havana
 
Linux Networking Commands
Linux Networking CommandsLinux Networking Commands
Linux Networking Commands
 
ClojureScript for the web
ClojureScript for the webClojureScript for the web
ClojureScript for the web
 
Building and Scaling Node.js Applications
Building and Scaling Node.js ApplicationsBuilding and Scaling Node.js Applications
Building and Scaling Node.js Applications
 
H2O World - What's New in H2O with Cliff Click
H2O World - What's New in H2O with Cliff ClickH2O World - What's New in H2O with Cliff Click
H2O World - What's New in H2O with Cliff Click
 

More from Rusty Klophaus

More from Rusty Klophaus (10)

Winning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test CycleWinning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test Cycle
 
Querying Riak Just Got Easier - Introducing Secondary Indices
Querying Riak Just Got Easier - Introducing Secondary IndicesQuerying Riak Just Got Easier - Introducing Secondary Indices
Querying Riak Just Got Easier - Introducing Secondary Indices
 
Masterless Distributed Computing with Riak Core - EUC 2010
Masterless Distributed Computing with Riak Core - EUC 2010Masterless Distributed Computing with Riak Core - EUC 2010
Masterless Distributed Computing with Riak Core - EUC 2010
 
Riak - From Small to Large - StrangeLoop
Riak - From Small to Large - StrangeLoopRiak - From Small to Large - StrangeLoop
Riak - From Small to Large - StrangeLoop
 
Riak - From Small to Large
Riak - From Small to LargeRiak - From Small to Large
Riak - From Small to Large
 
Riak Core: Building Distributed Applications Without Shared State
Riak Core: Building Distributed Applications Without Shared StateRiak Core: Building Distributed Applications Without Shared State
Riak Core: Building Distributed Applications Without Shared State
 
Riak Search - Erlang Factory London 2010
Riak Search - Erlang Factory London 2010Riak Search - Erlang Factory London 2010
Riak Search - Erlang Factory London 2010
 
Riak Search - Berlin Buzzwords 2010
Riak Search - Berlin Buzzwords 2010Riak Search - Berlin Buzzwords 2010
Riak Search - Berlin Buzzwords 2010
 
Riak from Small to Large
Riak from Small to LargeRiak from Small to Large
Riak from Small to Large
 
Getting Started with Riak - NoSQL Live 2010 - Boston
Getting Started with Riak - NoSQL Live 2010 - BostonGetting Started with Riak - NoSQL Live 2010 - Boston
Getting Started with Riak - NoSQL Live 2010 - Boston
 

Recently uploaded

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 

Recently uploaded (20)

10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
 
Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG Evaluation
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
PLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsPLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. Startups
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
The architecture of Generative AI for enterprises.pdf
The architecture of Generative AI for enterprises.pdfThe architecture of Generative AI for enterprises.pdf
The architecture of Generative AI for enterprises.pdf
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 

Everybody Polyglot! - Cross-Language RPC with Erlang

  • 1. EVERYBODY POLYGLOT! (Cross-Language RPC with Erlang) ErlangDC · December 2011 Rusty Klophaus - @rustyio Basho Technologies
  • 2. Languages have Strengths http://wordaligned.org/articles/distorted-software 2 @rustyio
  • 3. Connections are Hard Serialization Versioning & Upgrades Data Type Mismatches Speed, Bottlenecks & Back-Pressure Inadequate Tooling Context Switching 3 @rustyio
  • 4. Connections are Hard http://wordaligned.org/articles/distorted-software 4 @rustyio
  • 5. This Talk Create An Example Service Any service will do, just need a framework for discussion. Expose Application via Interfaces • REST / JSON via Webmachine & Spooky • Protocol Buffers via erlang-protobuffs • BERT-RPC via Ernie Server Code http://github.com/rustyio/ErlangRPCDemo 5 @rustyio
  • 6. This Talk Our Application: A Sequence Server Erlang service that returns a sequence of numbers. 1 sequence(N) -> 2 List1 = lists:seq(1, N), 3 List2 = [list_to_binary(integer_to_list(X)) || X <- List1], 4 {ok, List2}; 5 6 %% sequence(2). 7 {ok, [<<"1">>, <<"2">>]}. 8 9 %% sequence(5). 10 {ok, [<<"1">>, <<"2">>, <<"3">>, <<"4">>, <<"5">>]}. 11 12 %% sequence(50000). 13 {ok, [<<"1">>, <<"2">>, <<"3">>, <<"4">>, ...]}. 6 @rustyio
  • 7. Overview REST? Protocol Buffers? BERT-RPC? 7 @rustyio
  • 8. REST / JSON - Overview REST - Representational State Transfer Convention for talking to applications over HTTP Actions are Verbs are HTTP Methods (GET/PUT/POST/DELETE/...) Objects are nouns are URLs GET /users/5 JSON - Javascript Object Notation Encode data as parseable Javascript Understood by everything Human Readable {"id":5,"first":"Rusty","last":"Klophaus"} 8 @rustyio
  • 9. REST / JSON - Strengths & Weaknesses Strengths Simple, easy to poke around Good support in every language Composable - Caches, Reverse Proxies, Load Balancers Weaknesses General == More Handshaking/Metadata == More Overhead 9 @rustyio
  • 10. Protocol Buffers - Overview Protocol Buffers Developed by Google It’s not a protocol, it’s a format: • You provide the client / server logic • Useful for transmission AND storage Define data structures in .proto file, generate code http://code.google.com/apis/protocolbuffers/ https://github.com/ngerakines/erlang_protobuffs 10 @rustyio
  • 11. Protocol Buffers - Strengths & Weaknesses Strengths Compact Add fields without breaking existing applications • Versioning is not strict Weaknesses Configuration file (.proto) with new syntax to learn Generated code Uneven language support 11 @rustyio
  • 12. BERT-RPC - Overview BERT-RPC Developed by GitHub (Tom Preston-Werner) BERT = Binary Erlang Term • Encoding mimics native Erlang serialization http://bert-rpc.org https://github.com/mojombo/ernie 1 % Request 2 {call, ernie_sequence, sequence, [3]} 3 4 % Response 5 {response, {ok, [<<"1">>, <<"2">>, <<"3">>]}} 12 @rustyio
  • 13. BERT-RPC - Strengths & Weaknesses Strengths Easy to set up Agile Compact Weaknesses Uneven language support Less buzz than it deserves Not fully product-ized 13 @rustyio
  • 14. Requests & Responses What does the chatter look like? 14 @rustyio
  • 15. REST / JSON - Request & Response Request GET /sequence/3 HTTP/1.1 User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5 Host: localhost:8001 Accept: */* Response HTTP/1.1 200 OK Server: MochiWeb/1.1 WebMachine/1.9.0 (someone had painted it blue) Date: Wed, 23 Nov 2011 22:09:13 GMT Content-Type: application/json Content-Length: 21 ["1","2","3"] 15 @rustyio
  • 16. Protocol Buffers - Encoding rpc_demo.proto 1 message SequenceRequest { 2 required uint32 n = 1; 3 } 4 5 message SequenceResponse { 6 repeated bytes sequence = 1; 7 } 16 @rustyio
  • 17. Protocol Buffers - RPC Request 1 rpc_demo_pb:encode({sequencerequest, 3}). 2 <<8,3>> Response 1 rpc_demo_pb:encode({sequenceresponse, [<<"1">>, <<"2">>, <<"3">>]}). 2 <<10,1,49,10,1,50,10,1,51>> 17 @rustyio
  • 18. BERT-RPC - Encoding 1 term_to_binary([<<"1">>,<<"2">>,<<"3">>]). 2 <<131,108,0,0,0,3,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,1,51,106>> 3 4 5 bert:encode([<<"1">>,<<"2">>,<<"3">>]). 6 <<131,108,0,0,0,3,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,1,51,106>> 18 @rustyio
  • 19. BERT-RPC - Encoding 1 term_to_binary([<<"1">>,<<"2">>,<<"3">>]). 2 <<131,108,0,0,0,3,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,1,51,106>> 3 4 5 bert:encode([<<"1">>,<<"2">>,<<"3">>]). 6 <<131,108,0,0,0,3,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0,1,51,106>> 7 | | | | | | 8 | | | | | + Ascii value for '1' 9 | | | | + Length of string (1) 10 | | | + Next term is a string 11 | | + Length of list (3) 12 | + Next term is a list 13 + Start of Erlang term 19 @rustyio
  • 20. BERT-RPC - RPC Request 1 bert:encode({call, ernie_sequence, sequence, [5]}). 3 <<131,104,4,100,0,4,99,97,108,108,100,0,14,101,114,110, 4 105,101,95,115,101,113,117,101,110,99,101,100,0,8,115, 5 101,113,117,101,110,99,101,107,0,1,5>> Response 1 bert:encode({reply,{ok,[<<"1">>,<<"2">>,<<"3">>,<<"4">>,<<"5">>]}}). 2 3 <<131,104,2,100,0,5,114,101,112,108,121,104,2,100,0,2,111, 4 107,108,0,0,0,5,109,0,0,0,1,49,109,0,0,0,1,50,109,0,0,0, 5 1,51,109,0,0,0,1,52,109,0,0,0,1,53,106>> 20 @rustyio
  • 21. Show me the Client Code! 21 @rustyio
  • 22. REST / JSON - Clients CURL curl http://localhost:8001/sequence/5 Ruby Client 1 url = "http://localhost:8001/sequence/5" 2 resp = Net::HTTP.get_response(URI.parse(url)) 3 sequence = JSON.parse(resp.body) 22 @rustyio
  • 23. Protocol Buffers - Client Ruby Client 1 require 'beefcake' 2 3 class SequenceRequest 4 include Beefcake::Message 5 required :n, :int32, 1 6 end 7 8 class SequenceResponse 9 include Beefcake::Message 10 repeated :sequence, :string, 1 11 end 12 13 req = SequenceRequest.new(:n => 5) 14 Socket.tcp("localhost", 8003) do |socket| 15 socket.write(req.encode) 16 m = socket.read 17 return SequenceResponse.decode(m) 18 end 23 @rustyio
  • 24. BERT-RPC - Client Ruby Client 1 require 'bert-rpc' 2 3 svc = BERTRPC::Service.new('localhost', 9999) 4 sequence = svc.call.ernie_sequence.sequence(5) 24 @rustyio
  • 25. Show me the Server Code! 25 @rustyio
  • 26. REST / JSON - Server Spooky Server 1 -module(spooky_sequence). 2 -behaviour(spooky). 3 -export([init/1, get/2]). 4 5 init([])-> 6 [{port, 8002}]. 7 8 get(_Req, ["sequence", Num])-> 9 case sequence:sequence(Num) of 10 {ok, List} -> 11 {200, mochijson2:encode(List)}; 12 {error, Error} -> 13 {500, io_lib:format("~w", [Error])} 14 end; 15 get(_Req, _)-> 16 {400, "Usage: /sequence/:Num:"}. 26 @rustyio
  • 27. REST / JSON - Server Webmachine Server 1 -module(webmachine_sequence). 2 -export([init/1, content_types_provided/2, to_json/2]). 3 -include_lib("webmachine/include/webmachine.hrl"). 4 5 -record(ctx, { list }). 6 7 init([]) -> 8 {ok, #ctx {}}. 9 10 content_types_provided(RD, Ctx) -> 11 Types = [{"application/json", to_json}], 12 {Types, RD, Ctx}. 13 14 to_json(RD, Ctx) -> 15 {ok, List} = sequence:sequence(N), 16 Body = mochijson2:encode(List), 17 {Body, RD, Ctx}. 27 @rustyio
  • 28. Protocol Buffers - Server Erlang Server 1 %% Erlang RPC Demo 57 handle_info({tcp, _Sock, _Data}, State) -> 2 %% Copyright (c) 2011 Rusty Klophaus (@rustyio) 58 %% req =/= undefined: received a new request while another was in 3 %% See MIT-LICENSE for licensing information. 59 %% progress -> Error 4 60 lager:error("Received a new PB socket request" 5 -module(protobuff_server). 61 " while another was in progress"), 6 -behaviour(gen_server). 62 {stop, normal, State}; 7 63 8 -export([ 64 handle_info(_, State) -> % Ignore any late replies from gen_servers/messages from fsms 9 start_link/0, 65 {noreply, State}. 10 set_socket/2, 66 11 init/1, 67 terminate(_Reason, _State) -> 12 handle_call/3, 68 ok. 13 handle_cast/2, 69 14 handle_info/2, 70 code_change(_OldVsn, State, _Extra) -> {ok, State}. 15 terminate/2, 71 16 code_change/3, 72 %% =================================================================== 17 encode/1, 73 %% Handle PB Messages 18 decode/1]). 74 %% =================================================================== 19 75 20 -record(state, { sock }). 76 process_message(#sequencerequest { n = N }, State) -> 21 77 case sequence:sequence(N) of 22 -include("rpc_demo_pb.hrl"). 78 {ok, List} -> 23 79 Resp = #sequenceresponse { sequence = List }, 24 %% =================================================================== 80 send_msg(Resp, State); 25 %% Public API 81 {error, Reason} -> 26 %% =================================================================== 82 Msg = io_lib:format("~w", [Reason]), 27 83 Resp = #sequenceerror { message=Msg }, 28 start_link() -> 84 send_msg(Resp, State) 29 gen_server:start_link(?MODULE, [], []). 85 end. 30 86 31 set_socket(Pid, Socket) -> 87 %% Send a message to the client 32 gen_server:call(Pid, {set_socket, Socket}). 88 send_msg(Msg, State) -> 33 89 Pkt = encode(Msg), 34 init([]) -> 90 gen_tcp:send(State#state.sock, Pkt), 35 {ok, #state{}}. 91 State. 36 92 37 handle_call({set_socket, Socket}, _From, State) -> 93 encode(Msg) -> 38 inet:setopts(Socket, [{active, once}, {packet, 4}, {header, 1}]), 94 MsgType = element(1, Msg), 39 {reply, ok, State#state{sock = Socket}}. 95 [msg_code(Msg) | rpc_demo_pb:iolist(MsgType, Msg)]. 40 96 41 handle_cast(_Msg, State) -> 97 decode([MsgCode|MsgData]) -> 42 {noreply, State}. 98 MsgType = msg_type(MsgCode), 43 99 rpc_demo_pb:decode(MsgType, MsgData). 44 handle_info({tcp_closed, Socket}, State=#state{sock=Socket}) -> 100 45 {stop, normal, State}; 101 msg_code(#sequencerequest {}) -> 1; 46 handle_info({tcp_error, Socket, _Reason}, State=#state{sock=Socket}) -> 102 msg_code(#sequenceresponse {}) -> 2; 47 {stop, normal, State}; 103 msg_code(#sequenceerror {}) -> 3; 48 handle_info({tcp, _Sock, MsgData}, State=#state{sock=Socket}) -> 104 msg_code(Other) -> 49 Msg = decode(MsgData), 105 throw({unknown_pb_type, Other}). 50 case process_message(Msg, State) of 106 51 {pause, NewState} -> 107 msg_type(1) -> sequencerequest; 52 ok; 108 msg_type(2) -> sequenceresponse; 53 NewState -> 109 msg_type(3) -> sequenceerror; 54 inet:setopts(Socket, [{active, once}]) 110 msg_type(Other) -> 55 end, 111 throw({unknown_pb_code, Other}). 56 {noreply, NewState}; 28 @rustyio
  • 29. BERT-RPC - Server Ernie Server - Erlang BERT-RPC Server 1 %% FILE: ernie.config 2 [ 3 {module, ernie_sequence}, 4 {type, native}, 5 {codepaths, []} 6 ]. 1 -module(ernie_sequence). 2 -export([sequence/1]). 3 4 sequence(N) -> 5 sequence:sequence(N). 29 @rustyio
  • 30. Benchmarks How fast is it? 30 @rustyio
  • 31. Benchmarks Disclaimers Benchmarking is hard The shape of your data matters (size and complexity) Speed is not the only objective 31 @rustyio
  • 33. Encoding Speed - 5 items BERT JSON PB 33 @rustyio
  • 34. Encoding Speed - 50 items BERT JSON PB 34 @rustyio
  • 35. Encoding Speed - 500 items BERT JSON PB 35 @rustyio
  • 36. Encoding Speed - 5,000 items BERT JSON PB 36 @rustyio
  • 37. Encoding Speed - 50,000 items BERT JSON Sad Protocol Buffers :( 37 @rustyio
  • 38. Encoding Speed - Ruby | 5 | 50 | 500 | 5,000 -----+---------+---------+---------+---------- JSON | 0.03 ms | 0.77 ms | 0.47 ms | 4.21 ms PB | 0.07 ms | 0.60 ms | 7.37 ms | 197.24 ms BERT | 0.08 ms | 0.52 ms | 4.97 ms | 52.42 ms 38 @rustyio
  • 39. Encoding Speed Interpretations BERT wins in Erlang, because it’s native. JSON wins in Ruby. Protocol Buffers is slow all around for complex data. • Note: This is different from large data. 39 @rustyio
  • 40. Benchmarks: Single Hop $ ping dell.local PING dell.local (192.168.2.2): 56 data bytes 64 bytes from 192.168.2.2: icmp_seq=0 ttl=64 time=0.490 ms 40 @rustyio
  • 41. Benchmarks More Disclaimers First approach exhausted TCP connections “Fixed” by tunneling connections, which impacts results 41 @rustyio
  • 42. Operation Performance - 5 items BERT PB PB SPOOKY WEBMACHINE 42 @rustyio
  • 43. Operation Performance - 50 items BERT PB PB SPOOKY WEBMACHINE 43 @rustyio
  • 44. Operation Performance - 500 items BERT PB PB SPOOKY WEBMACHINE 44 @rustyio
  • 45. Operation Performance - 5,000 items BERT PB PB SPOOKY WEBMACHINE 45 @rustyio
  • 46. Encoding Speed Interpretations Performance is fairly even for simple data. PB is clear loser for data with lots of items. Webmachine pays a tax for considering entire HTTP decision tree. Take these with a grain of salt, everything is tunneled over SSH. 46 @rustyio
  • 47. Webmachine - HTTP Decision Tree 47 @rustyio
  • 48. Benchmarks: Multiple Hops $ ping rusty.io PING rusty.io (173.203.217.46): 56 data bytes 64 bytes from 173.203.217.46: icmp_seq=0 ttl=53 time=49.550 ms 48 @rustyio
  • 49. Operation Performance - 5 items BERT PB PB SPOOKY WEBMACHINE 49 @rustyio
  • 50. Operation Performance - 50 items BERT PB PB SPOOKY WEBMACHINE 50 @rustyio
  • 51. Operation Performance - 500 items BERT PB PB SPOOKY WEBMACHINE 51 @rustyio
  • 52. Operation Performance - 5,000 items BERT PB PB SPOOKY WEBMACHINE 52 @rustyio
  • 53. Operation Performance - Multiple Hops Interpretations No clear winner. Network speed / variability is the bottleneck. Take these with a grain of salt, everything is tunneled over SSH. 53 @rustyio
  • 54. The Results Recommendations Start with REST / JSON Optimize for performance with Protocol Buffers Get adventurous with BERT-RPC • Easy to set up == Easy to back out Get Involved! Protocol Buffers NIF? JSON NIF? General Ernie (BERT-RPC) improvements: • Re-use connections, better packaging & documentation 54 @rustyio
  • 55. Honorable Mentions Other RPC Frameworks: Thrift - http://thrift.apache.org/ (Originally Facebook) Avro - http://avro.apache.org/docs/current/ XML-RPC CORBA - http://www.erlang.org/doc/man/corba.html UBF - http://www.sics.se/~joe/ubf/site/home.html MsgPack - http://msgpack.org/ Etch - http://incubator.apache.org/projects/etch.html ASN.1 - http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One Erlang <-> Other Code: Erlang "ports" - integration via stdin/stdout. Bifs - Extend Erlang with new functions. "Fake" Erlang Nodes: JInterface (it is... not great) C Nodes - http://www.erlang.org/doc/tutorial/cnode.html 55 @rustyio
  • 56. Related Talks • Anton Lavrik - Piqi-RPC: exposing Erlang services via JSON, XML and Google Protocol Buffers over HTTP http://www.erlang-factory.com/conference/SFBay2011/speakers/AntonLavrik • Tom Preston-Werner - BERT is to Erlang as JSON is to JavaScript http://www.erlang-factory.com/conference/ErlangUserConference2009/speakers/ TomPrestonWerner • Todd Lipcon - Thrift Avro/Erlang Bindings http://www.erlang-factory.com/conference/SFBay2010/speakers/toddlipcon • Cliff Moon - Building Polyglot Distributed Systems with Jinterface http://www.erlang-factory.com/conference/SFBay2011/speakers/CliffMoon • Kresten Krab Thorup - Erjang - A JVM-based Erlang VM http://www.erlang-factory.com/conference/SFBay2010/speakers/ KrestenKrabThorup • Yurii Rashkovskii - Beam.JS: Erlang meets JavaScript http://www.erlang-factory.com/conference/SFBay2011/speakers/YuriiRashkovskii 56 @rustyio
  • 57. Thanks! Questions? 57 @rustyio