Erlang gen_server template

I like Erlang and I like gen_servers, I end up coding a lot of stuff as gen_servers and I like behaviors in generally. I even wrote some myself. I haven’t used Erlang for a while. I’ve been playing with it in the last couple of days, hopefully I’ll announce something soon.

I ended up creating my own gen_servers template to get started. It’s a very verbose one and I’m putting it here more for me to know where it is that anything else; but, maybe it’s of use for someone else:

-module(module).
-compile(export_all).

-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

%% Public API

start() ->
  gen_server:start({local, ?MODULE}, ?MODULE, [], []).

stop(Module) ->
  gen_server:call(Module, stop).

stop() ->
  stop(?MODULE).

state(Module) ->
  gen_server:call(Module, state).

state() ->
  state(?MODULE).

%% Server implementation, a.k.a.: callbacks

init([]) ->
  say("init", []),
  {ok, []}.


handle_call(stop, _From, State) ->
  say("stopping by ~p, state was ~p.", [_From, State]),
  {stop, normal, stopped, State};

handle_call(state, _From, State) ->
  say("~p is asking for the state.", [_From]),
  {reply, State, State};

handle_call(_Request, _From, State) ->
  say("call ~p, ~p, ~p.", [_Request, _From, State]),
  {reply, ok, State}.


handle_cast(_Msg, State) ->
  say("cast ~p, ~p.", [_Msg, State]),
  {noreply, State}.


handle_info(_Info, State) ->
  say("info ~p, ~p.", [_Info, State]),
  {noreply, State}.


terminate(_Reason, _State) ->
  say("terminate ~p, ~p", [_Reason, _State]),
  ok.


code_change(_OldVsn, State, _Extra) ->
  say("code_change ~p, ~p, ~p", [_OldVsn, State, _Extra]),
  {ok, State}.

%% Some helper methods.

say(Format) ->
  say(Format, []).
say(Format, Data) ->
  io:format("~p:~p: ~s~n", [?MODULE, self(), io_lib:format(Format, Data)]).

Update 2010-01-04: I keep changing the actual contents of the template as I’m coding a little Erlang app. I’ve recently added, among other things, a call to get the state of the process, useful for debugging.

Erlang, the language for network programming Issue 2: binary pattern matching

Much is being said about the excellent capabilities of Erlang to write distributed fault-tolerant programs, but little has been said about how easy and fun it is to write servers (those programs at the other end of the line) with it. And by easy I don’t just mean that you can put up a web server in two lines of code and hope it’ll work, I mean it’ll be easy to built robust servers.

One example of this is ejabberd, a free Jabber server.

I’ll start this second part, the one with real networking programming, with a bet. Think about the IPv4 protocol, its header is like this:

0                   1                   2                   30
  1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type of Service|          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |Flags|      Fragment Offset    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

you can check RFC791, page 11 for more information. At a glance, the first 4 bits are the version, the next 4 bits the IHL (Internet Header Length), then we have a whole byte, 8 bits, of Type of Service. The next two bytes are the total length and I am already tired of it, you get the picture right?

Pick whatever language you want (except Erlang, that’s mine now, but it can be yours latter) and think about how many lines of code would take you to parse that beast, the IP header. Think about how much time it takes you to write those lines, and test them.

Done? come on! really think about it, otherwise the game is boring. Close your eyes, picture the lines of code. If you can’t, go and write some pseudo-code similar to your favorite language to do the parsing. Done? OK.

Here’s my bet: I bet that I can do it, in Erlang, in far less lines than you! I bet you that I can code it so fast that I’d be finished of writing the code to parse the whole header before you finish the code to parse the first line. And while you are testing I’ll go to the beach because I’ll just trust my code to run without problems.
Continue reading

Erlang, the language for network programming Issue 1: pattern matching

Much is being said about the excellent capabilities of Erlang to write distributed fault-tolerant programs, but little has been said about how easy and fun it is to write servers (those programs at the other end of the line) with it. And by easy I don’t just mean that you can put up a web server in two lines of code and hope it’ll work, I mean it’ll be easy to built robust servers.

One example of this is ejabberd, a free Jabber server.

One of the Erlang features that let us write servers is its binary pattern matching. But to understand binary pattern matching first you have to understand pattern matching.

Let’s start with a classic of functional programming: factorial. This is factorial in Erlang

fac(N) ->
   if N == 0 -> 1;
      true -> N * fac(N - 1)
   end.

Continue reading