Irrational Exuberance!

Getting Started With BeepBeep

July 5, 2009. Filed under erlangbeepbeep

A coworker (need to figure out his hidden blog so I can link back to him... :) forwarded a message my way from an Erlang mailing list regarding BeepBeep, which seemed like a fairly exciting project given that it combines something I am using at work but need more practice with--Erlang--and flavors it with a familiar spice: Django.

This tutorial will walk through installation, creation and (kind-of, sort-of, but not really) deployment of an extremely simple BeepBeep application. I can't promise you'll be immediately overwhelmed with excitement, but this will pave the way for more exciting tutorials down the line.

Please note that this tutorial owes a heavy debt to the BeepBeep documentation, and wouldn't have been possible without it.


In this tutorial we will build a simple web application that will display random prime numbers (my standard for webapps seems to have fallen a bit low these days), while displaying the basic components of a BeepBeep app. Without further ado, let's get started.

Installing BeepBeep

  1. First, install Erlang. For OS X with Port this could be sudo port install erlang, for Debian systems it could be apt-get install erlang.

  2. Next, download the source code from the Git repository.

    cd ~/git/
    git clone git://github.com/dmitriid/beepbeep.git
    

    (At the time of this tutorial's writing, the latest commit was 96fb57a58322aa9abd0340755f0c94d6501d223d from July 2nd, 2009. If you really want this tutorial to work without modification, I'd recommend using that version.)

  3. Third, we need to build the BeepBeep source code. (The Git repository is kind enough to come with its dependencies--MochiWeb and ErlyDTL--included.)

    cd beepbeep
    make
    

    Somewhat unusually, building the code worked on the first try, and didn't involve chasing down any hidden dependencies.

Now you've completed the rather painless BeepBeep installation.

Creating a BeepBeep Project

Now that we've installed the framework, our next step is to create the foundation of our new project.

  1. First, create the project scaffolding for the BB_Primes, the exceedingly unclever name for the project we're building.

    ./script/new_beep.erl Primes ../BB_Primes
    
  2. Now start the webserver for the new project.

    cd ../BB_Primes/primes/
    make
    ./stat_server.sh
    

    If you forget to make the code you'll get a fairly generic crash file, so double-check there first if something goes wrong.

    After successfully running the server, go to http://localhost:8000 to view the default BeepBeep application page.

  3. Now let's take a few minutes to take a look at the various files and folders that are created by the new_beep.erl script.

    • deps contains the BeepBeep, MochiWeb and and ErlyDTL sources, which means you don't need to ensure those are in your Erlang path. Not too much to do here, although you might want to add other dependencies your project uses.

    • ebin stores the compiled files generated by the Makefile. Not much to do here either.

    • support contains include.mk, a helper file for make.

    • www contains static files to be served by MochiWeb. (I must admit, I assumed a production environment using BeepBeep would involve hiding it behind Nginx/Lighttpd and only using it to serve dynamic content, but it seems that MochiWeb is a reasonable static file server as well.)

    • views contains the templates used to render to your apps pages. These templates are written in the Django template language, compiled using ErlyDLT.

    • src contains all the code for the application, including several pieces that will be unfamiliar to those without previous Erlang experiences.

      • home_controller.erl is where your controller logic is defined. For simple applications, this is the only file in src that you'll need to edit.
      • primes.app defines an OTP application.
      • primes.erl defines the start and stop functions for primes.app.
      • primes_deps.erl defines and locates dependencies (I haven't actually seen a X_deps.erl file before, a rather nice idea for reusable apps.)
      • primes_app.erl starts and stops the primes_sup.erl supervisor application.
      • primes_sup.erl defines the supervisor for primes.app.
      • primes_web.erl defines the MochiWeb server for the app.

Customizing a BeepBeep Project

There are three primary locations where you'll be making changes to your BeepBeep projects.

  1. src/home_controller.erl is where URL patterns and behavior are defined. In Django terms, it serves as both the urls.py and views.py files for your project.

  2. views/ contains all templates, which are used by controllers to display content to users. In Django, this would be your templates/ folder.

  3. www/ contains all static media, akin to the media/ folder for most Django projects.

In general, I would recommend starting with a simple controller, writing a simple view to match, and then iterating between the two until reaching your desired ending point. Finally add static files at the very end.

Following my own advice, first let's open up src/home_controller.erl. Find the index handle which looks like this:

handle_request("index",[]) ->
    {render,"home/index.html",[{data,"Hello There From BeepBeep!"}]};

and modify it to look like:

random_prime(N) ->
    % skipping the logic for finding
    % nth prime to keep things concise ;(
    101.

handle_request("index",[]) ->
    N =	random:uniform(100),
    SomePrime =	random_prime(N),
    {render, "home/primes.html", [{prime, SomePrime}]};

Next it is time to work on our views. First open up views/base.html.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
 <title>Welcome to Primes</title>
 <link href="/stylesheets/style.css" rel="stylesheet" type="text/css"/>
</head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>

The base.html template is used as scaffolding for other templates, and is a simple way to support the Don't Repeat Yourself philosophy from Django. We will then extend it into the home/primes.html template.

{% extends "../base.html" %}
{% block content %}
    <p>Prime is : {{ prime }}</p>
{% endblock %}

Now finally make the application again.

will-larsons-macbook:primes will$ make
(cd src;make)
erlc -W -I ../include -I ../deps/beepbeep-src/include -pa ../deps/beepbeep-src/ebin -pa ../deps/erlydtl-src/ebin -pa ../deps/mochiweb-src/ebin +debug_info -o ../ebin home_controller.erl
./home_controller.erl:8: Warning: variable 'N' is unused

Woops, have a warning there because I backtracked on implementing the prime code, but nothing too important.

Now start the server again:

./start-server.sh 

If you had (hypothetically, of course) typoed home/prime.html instead of home/primes.html in your controllers file, then you would see an error like this:

BeepBeep error message page.

It isn't quite as pretty or as informative as the Django error pages, but it's servicable nonetheless. A successful run looks like this:

BB_Prime running successfully.

Right now it is using the default BeepBeep stylesheet at www/stylesheets/style.css, but let's change things up ever so slightly.

emacs www/stylesheets/primes.css

And add these styles:

body {
     padding: 25px; 
     background: #333;
     color: #BBF;
}

Then edit views/base.html to replace

<link href="/stylesheets/style.css" rel="stylesheet" type="text/css"/>

with

<link href="/stylesheets/primes.css" rel="stylesheet" type="text/css"/>

Now restart the server,

./start-server.sh

reload the page, and bask in the glory of the very simple application you have created.

Deployment

The current start script runs in the current shell session, which is great for development, but less convenient for long-running processes. You could go very far in improving it (start it in an alternate node, run it using heart, etc), but keeping with the simple tone of this tutorial it is easy to simply run it in detached mode which allows you to retain your shell sessions.

cp start-server.sh start-detached-server.sh
emacs start-detached-server.sh

Then modify start-detached-server.sh to look like this:

#!/bin/sh
cd `dirname $0`

exec erl -pa $PWD/ebin $PWD/deps/*/ebin -boot start_sasl \
-s reloader -s primes -detached

If you want the process to persist after you logout, you can use sudo -u to run the process as a persistent user (running as root has some ever-so-minor security consequences, but one might use www-data or a custom user to run your BeepBeep app).

So there you have it, a very simple BeepBeep application. This tutorial admittedly doesn't give you the Blog in 5 Minutes feel that you've probably come to expect from frameworks, but hang around and I promise the next BeepBeep tutorial will be much more exciting.

(The code from this tutorial is available as BB_Primes in the BeepBeep Examples git repository.

As always, I am grateful for any feedback or corrections!