Erlang for everyday use (3)




Since my previous post I found a little bug in the CEAN installation. Or maybe it's just not very well documented thing:
After the installation the path to the control socket is pointing by default to /usr/local/var:

=ERROR REPORT==== 25-Jun-2007::10:37:24 ===
Failed to create/manipulate the ctlfile 
called /usr/local/var/run/yaws/ctl-default
Either problems with permissions or  earlier runs of yaws 
with the same id  <default> as this, check dir for perms
None of Yaws ctl functions will work

Seems during the compilation you can control where the control socket will be via VARDIR environment variable, but we installing from binaries, so...!? I couldn't find a way to set this path during the run time.
For me I solved the problem by recompiling the ${CEAN}/erlang/lib/yaws-1.68/src/yaws_generated.erl and replace the original ebin/yaws_generated.beam file:

$ cd ${CEAN}/erlang/lib/yaws-1.68/src/
%% correct the paths inside the yaws_generated.erl
%% to point to the CEAN install directory
$ erlc yaws_generated.erl
$ mv yaws_generated.beam ../ebin

OK, let's go back to the today's topic

Erlang project directory structure

Like all we know:

"Convention over Configuration" means a developer only needs to specify unconventional aspects of their application.
-- Wikipedia, Ruby On Rails

What is the typical erlang project structure?

  • ebin/ - directory with compiled .beam files - in general you need to deploy only them to the remote location
  • src/ - directory with source .erl files
  • include/ - directory with .hrl files, defining macros, records etc.
  • priv/ - application specific configuration, docroot for the yaws-based projects

And because I know you are lazy here is an escript to automate the erlang project directory creation. Usage:

$ wget -O ~/bin/rails && chmod 755 ~/bin/rails
$ rails ~/Work/erlang/erl_first

Oops, mistake. Better name it erlday, not rails, you still need your good old Rails, do you? ;)

How can you recompile all your sources? What about the Makefile? Or Rakefile? Good news for the Windows guys: You just don't need all of them!

  • On the top of your project directory create a file with name Emakefile and content:
{"src/*", [debug_info, {outdir, "ebin"}, {i,"include"}]}.
  • Start the erlang shell and type make:all().
  • There is no step 3 ;)

If you are using the erlday escript, it will create automatically the Emakefile for you.

How to find where are make module sources:

$ erl
1> code:which(make).

so it will be .../src/make.erl.
Practice - comet chat with yaws

And because only reading is not good, here something to play with - Comet-based, yaws-powered chat.

WARNING! The Comet application sources belong to Mikage-san. I only changed the messages to be in English. And because there was nothing mentioned about the licensing, I put a link with the original sources in the beginning of the files.

$ mkdir ~/Work/erl_comet && cd ~/Work/erl_comet
$ wget && tar xvzf erl_comet.tgz
  • Adjust the paths to the installation directory
    • src/chat.erl - path to the yaws.hrl file
    • priv/yaws.conf - path to the log directory, address, port, and path to docroot.
    • priv/docroot/index.yaws - the URL to your template file

  • Recompile everything and quit the erlang shell session (Ctrl+G):
$ erl
1> make:all().
Recompile: src/chat

Note: Specially for that project I included a Makefile, so you can use make and make run.

  • Start the application
$ make run
=INFO REPORT==== 25-Jun-2007::11:56:31 ===
Yaws: Using config file priv/yaws.conf
yaws:Add path "/home/erl/cean/erlang/lib/yaws-1.68/examples/ebin"
yaws:Running with id="comet"
Running with debug checks turned on (slower server) 
Logging to directory "/home/erl/cean/var/log"

=INFO REPORT==== 25-Jun-2007::11:56:31 ===
Yaws: Listening to for servers
 - http://localhost:4080 under /home/erl/Work/erlang/erl_comet/priv/docroot

=INFO REPORT==== 25-Jun-2007::11:56:31 ===
sync call chat:start

Next time - inets, pico and yaws deployment. Or something else, if there are requests...
I'll be in vacation for about 10 days, so be patient... ;)