Rafael Wenzel bio photo

Rafael Wenzel

Lead DevOps Engineer

Twitter Github Stackoverflow

In this new article series that I call Adventures in Erlang I am trying to teach the readers how to properly start an Erlang endeavor on their own.

Please note that this article prerequisites Erlang/OTP 18 as well as Rebar as a package manager, in order to follow on your own system. I further assume that you are running on a Linux operating system. If you are running on anything else, you need to adapt the commands respectively.

I have created a free github project for this article series, that you can find here.

If you want to learn more about the Erlang syntax, and all the stuff we use in these articles, please refer to the rather awesome free online book Learn you some Erlang.

Beginning

We start our brand new application with some nifty features presented by Rebar.

$ rebar create-app appid=adventures
==> adventures-in-erlang (create-app)
Writing src/adventures.app.src
Writing src/adventures_app.erl
Writing src/adventures_sup.erl

This creates our first full application with everything we need to properly run it. But before we can compile and run it, we need to make some little changes for it to properly have code in it.

First server

We need something that the main application can actually run for us, that’s why we create ourselves a little server. Don’t worry, our secret little helper called Rebar has just the right tools we need.

$ rebar create template=simplesrv srvid=adventures_server
==> adventures-in-erlang (create)
Writing src/adventures_server.erl

Now for the sake of simplicity we just make sure, that we know when the server is actually starting. So we change the init/1 function in the file we just created to the following:

init(Args) ->
    io:format("Our server started~n", []),
    {ok, Args}.

Adding to the supervisor

Now we need to add our newly created server to the supervisor file we created earlier, called adventures_sup.erl. Here we change the init/1 function to the following:

init([]) ->
    {ok, { {one_for_one, 5, 10}
      , [?CHILD(adventures_server, worker)]
    }}.

Basically we use the define from the top of the same file, to add our server into that rather complicated (not really, but it can be confusing for beginners) supervisor syntax.

Compile and run

Now comes the great moment we try to actually compile and run our code.

In order to properly test everything, we take our perfect little helper Rebar again, and let it do the tasks.

$ rebar compile
==> adventures-in-erlang (compile)
Compiled src/adventures_app.erl
Compiled src/adventures_server.erl
Compiled src/adventures_sup.erl

Now in order to run it, we first need to switch to the ebin directory, that has been created and run the erlang shell, also called REPL:

/ebin$ erl
Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V7.1  (abort with ^G)
1> application:start(adventures).
Our server started
ok
2> application:which_applications().
[{adventures,[],"1"},
 {stdlib,"ERTS  CXC 138 10","2.6"},
 {kernel,"ERTS  CXC 138 10","4.1"}]
3>

We can see that our application runs properly.

Final conveniences

Now it is nice that our application runs and all, but it is a little inconvenient how we have to switch to the ebin directory, and manually starting our app in the REPL. What we want to have is a nifty little start script, that we are going to configure now.

As a last preparation though, we need to add a function to our application file adventures_app.erl, called start/0 and also add it to the -export parameter:

-export([start/0, start/2, stop/1]).

start() -> start([],[]).

This is needed so that our little run script is able to easily start our application.

Finally we are creating a little script called run.sh with the following content (with courtesy to erlang-irc-bot):

#! /bin/sh
BASEDIR=`dirname $0`
BASEDIR=`readlink -f $BASEDIR`
cd $BASEDIR

ERL_LIBS=$BASEDIR:$BASEDIR/deps
export ERL_LIBS

SNAME=adventures@localhost


if [ "$1" = "shell" ]; then
    erl -remsh $SNAME -sname rem
else
    exec erl +K true -noinput -noshell \
        -sasl errlog_type error \
        -sname $SNAME \
        -s adventures_app
fi

With this we have the awesome opportunity to either just run our server with executing the file, or we can even use this script to get into the application environment, for debugging purposes.

$ ./run.sh
Our server started

You can easily get out of this with hitting CTRL+C followed by a to abort the script. Or, we open another terminal, while we leave our server running, and check our nifty debugging console:

$ ./run.sh shell
Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V7.1  (abort with ^G)
(adventures@localhost)1>

Conclusion

After finalizing the app description in the adventures.app.src file, and also adding a rebar.config file for future use, I committed the whole thing to the mentioned git repository.

We saw that creating a simple erlang application base stump is pretty easy with the use of Rebar, and you can easily get started with a clean application within minutes.

In the next few articles to this series, I will add some functionality to this, and see how we can create a full application consisting of different application parts that are needed for our full server implementation.