Erlang on the Web

July 22, 2009

If you’re thinking about using Erlang for your next web application, here’s an IEEE Internet Computing article I co-authored with Steve Vinoski that’ll help get you started:

“Web developers find that the Erlang programming language originally conceived more than 20 years ago for building long-running, fault-tolerant, highly concurrent telephony systems is well-suited for server-side Web applications.”

Build your next web app with Erlang

“This material is presented to ensure timely dissemination of scholarly and technical work. Copyright and all rights therein are retained by authors or by other copyright holders. All persons copying this information are expected to adhere to the terms and constraints invoked by each author’s copyright. In most cases, these works may not be reposted without the explicit permission of the copyright holder.”

rinterface: a pure Ruby client to talk to Erlang

May 20, 2009

After digging through the jinterface code for the past couple of evenings I finally have a working Ruby client that can make RPC calls to an Erlang node. Although the code is a bit rough right now, it works.

I’m hoping to evolve it into a full Ruby node with capabilities similar to jinterface (the java implementation included with the Erlang).

The current implementation has a few limitations:

  1. The Erlang node and Ruby client must be running on the same machine. This will not be hard to change
  2. The Erlang process must have a registered name

Essentially right now it works a lot like the native rpc:call in Erlang.

Here’s an example of a Ruby client calling a Erlang process called ‘math’:


EM.run do
  # Connect to epmd to get the port of 'math'.
  # 'math' is the -sname of the erlang node
  epmd = EpmdConnection.lookup_node("math")
  epmd.callback do |port|
    puts "got the port #{port}"

    # make the rpc call to 'math' on port for
    # mod 'math_server' on fun 'add' with args
    node = Node.rpc_call("math",port.to_i,
                                  "math_server",
                                  "add",[10,20])
    node.callback{ |result|
      puts "Sum is: #{result}"
      EM.stop
    }

    node.errback{ |err|
      puts "Error: #{err}"
      EM.stop
    }
  end

  epmd.errback do |err|
    puts "Error: #{err}"
    EM.stop
  end
end

You can check out the code here: rinterface

Getting started with BeepBeep

May 14, 2009

I’ve finally had a little time to work on BeepBeep. With this time, I’ve updated some of the docs included with source code, updated the Blog demo app to the latest code base, and moved the demo app into the code base versus a separate project. I also wrote up a little tutorial to get you started:

This is a quick tutorial of creating a web application with BeepBeep. For more details on BeepBeep see the documention and a complete blog example included with the source code.

The tutorial covers:

  • How to create a new application
  • How to implement a controller
  • How to create a template

Read more here…

Connecting to Erlang’s epmd from Ruby

April 24, 2009

Lately I’ve been experimenting with creating a pure Ruby library to communicate with Erlang nodes similar to the capabilities offered by the jinterface included with Erlang.  Using a combination of the Java source code for jinterface and the documention, I’ve had moderate success getting my code to talk to epmd (Erlang Port Mapping Daemon) and pass the intial Erlang “secret” handshake.

If you’re not familiar with epmd, it’s job is to essentially help nodes find one another.  When you start an Erlang node it’ll automatically pass some information about itself to epmd so other nodes can find it. The epmd runs by default on port 4369 and is started automatically when you run an Erlang application (if it’s not running already). There are basically two important requests a node makes to epmd: 1) register itself with epmd and 2) given a name of another node, lookup it’s port.  The format of the requests are documented here.

To look up the port of another Erlang node from Ruby (or any other language).  Here’s what you need to do:

1. Make a TCP connection to epmd on port 4369

2. Send the port lookup request in the following format

n = name of the node we're interested in
| 2 bytes | 1 byte | nodename.size |
----------------------------------------------------
| n + 1    |  122    |           n            |
Where 122 is the tag for port lookup

3. Read the response from epmd. It’ll be in this format

| 1 byte | 1 byte | 2 bytes |
--------------------------------------
|  119   | result   |  port#   |

Where:119 is the response tag
result > 0 means we were successful
port# is the port number of the node
There's more information after the port, but we'll ignore
that for now.

Finally here’s some code to try it out (requires the excellent eventmachine):

ruby_2_epmd.rb

To run the example:

1. Start an erlang node in one terminal “erl -sname hello”
2. In another terminal run the ruby code.

If sucessful you should get back the port number of the “hello” node.

BeepBeep obligatory blog demo

December 12, 2008

This code shows how to build a simple application with BeepBeep. It demonstrates a simple application flow and the use of filters for authentication.

* UPDATE * The blog demo is not included with the beepbeep source code

Download it here: Blog Demo

It’s completely standalone, so all you need is Erlang and some curiousity.

Setup

- Download the code
- CD into the beebeep_blog_example directory
- run make
- run ./start-server.sh
- point your browser to http://localhost:8000

Since BeepBeep generates the core code and structure for you, the only code I needed to write for this app was:

- src/main_controller.erl – The controller for displaying and creating posts
- src/login_controller.erl – The controller for handling login
- the templates for the app, located in the template directory
- Oh, and the simple blog_db, used to store blog entries in-memory

Go on…give it a try!

BeepBeep: A Rails like framework for Mochiweb

December 12, 2008

BeepBeep is a simple web application framework for Erlang inspired by Rails and Merb. It follows the principle of convention over configuration - meaning if you follow the code structure layout and a few rules when building your app, it’ll require no extra work on you behalf to map Url requests to your Controllers and Views.

BeepBeep is built on Mochiweb and erlyDTL, providing a super fast web server and the ability to define your templates with the Django template language.

Features:

  • A Script to generate a new web application (based on mochiweb’s approach)
  • Session Server to store your application state
  • Before filter on your controllers for things like authentication
  • Django templates for the view

Getting Started:

  1. download the code here: BeepBeep
  2. CD into the beepbeep directory
  3. run make
  4. generate a new web application by running ./script/new_beep.erl YouAppName “DestinationDirectory

This will create a web app with everything you need. It includes a sample controller (main_controller.erl).

To run the sample:

  1. Cd into the new application’s directory you created above and start the server: ./start-server.sh
  2. Open a browser and visit “http://localhost:8000″

How it works:

You write a controller similar to how you’d write a “gen_server” based app, but in our case you use the included “gen_controller” behavior. In the controller you define the functions you want to expose to requests. BeepBeep will automatically map Url requests to controller and functions (or actions). For example a request to “/hello/show” would map to the “hello_controller” and invoke the “show” function.

Here’s a controller example:

%% hello_controller.erl
-module(hello_controller).

-export([show/1]).
-export([handle_request/2, before_filter/1]).

-behaviour(gen_controller).
-include("beepbeep.hrl").

show(Params) ->
    gen_controller:call(?MODULE,index,Params).

%% Callback for show
handle_request(show,Params) ->
    {render, "hello/show.html",[{name,"BeepBeep"}],Params}.

%% Callback filter for things like authentication (not using it here)
before_filter(Params) ->
    {ok}.

From “handle_request” we return a tuple that tells the framework what template to use. Templates are located in the template directory. In our example we’ll use the template located in the subdirectory “hello” and the file “show.html”

Here’s an example of the “show.html” template:

 <h2>Hello from {{ name }} </h2>

Which will result in:

<h2>Hello from BeepBeep</h2>

The “name” key set in the controller is passed to the template and expanded using the Django format via erlyDTL.

This BeepBeep approach provides a clean separation of the erlang logic in the controller and the html code in the template.

More to come…

Erlang init.d script in Ubuntu

November 25, 2008

Problem

You’ve created an init.d script for your Erlang application. When logged in the script works and starts the app, however it’s not working on boot.

Solution

  1. Make sure /usr/local/bin/ is recognized in the profile
  2. export HOME in you init.d script that points to the directory with your erlang cookie

VMWare Ubuntu copy can’t find network

November 25, 2008

Problem

You created an Ubuntu VMWare appliance and copied to another location. When booting up the copy the network interfaces are not recognized. Well really you only get the local interface.

Solution

The problem is the mac address is different than the one in the vmx file. Quick fix is to simply delete the file:

/etc/udev/rules.d/70-persistent-net-rules

in the original OS *before* copying it. So delete the file, shutdown the OS, then copy it over. On the first boot in the copy, Ubuntu will generate the file above with the correct mac address and all should be working.

Create a signature of your data with Erlang

October 27, 2008

-module(signit.erl).
-export(start/0,sha_sign/0).

start() -> application:start(crypto).

%% Sign the data using SHA.
%% This will return a 20 byte key for the data
sha_sign(Data) ->
    Sha_data = crypto:sha(Data),
    Sha_list = binary_to_list(Sha_data),
    lists:flatten(list_to_hex(Sha_list)).

%% Crypto doesn't have a hexdigest method. I found the code below
%% here
%% Convert Integer from the SHA to Hex
list_to_hex(L)->
       lists:map(fun(X) -> int_to_hex(X) end, L).

int_to_hex(N) when N < 256 ->
       [hex(N div 16), hex(N rem 16)].

hex(N) when N < 10 ->
       $0+N;
hex(N) when N >= 10, N < 16 ->
       $a + (N-10).

Mochiweb to Scalaris example

July 26, 2008

I’ve created a simple HTTP interface with MochiWeb that allows you to read and write key/Value pairs to Scalaris. The REST “like” interface is very simple:

To write, send a request to: “http://localhost:8002/scalaris/write” with the parameters key=”your_key”, value=”your_value”

To read, “http://localhost:8002/scalaris/read” with the parameters key=”your_key”

The code uses a gen_server process that makes an rpc:call to the Scalaris API.

You can check out the code here: mochiweb-scalaris


I found a sample essay, possibly better essay writing help, read more...