On RabbitMQ and Erlang

After reading the book RabbitMQ in Action: Distributed Messaging for Everyone, I still found myself googling for more examples. It’s a very good book in the sense that it covers managing RabbitMQ and a lot of linux system admin examples that developers should know if they will use RabbitMQ in production for their apps.

The book has a lot of Python examples. It’s not that I can’t get it to work but I just think that it’s a good time to learn a new language called “Erlang.”

I find this site learnyousomeerlang.com very amusing and very informative. Read it if you like to learn about the language. Of the few things I like about it so far is its simplicity.

In Lua, we have tables as dictionaries:

t = { apple="green", orange="orange", banana="yellow" }

In Erlang, we have lists:

{ Apple="green", Orange="orange", Banana="yellow" }.
green, orange, yellow

Or with “atoms,” constants with their own name for value.:

{green, orange, yellow}.
green, orange, yellow

Erlang is a language developed by Ericsson for their telephone switching gear. It is now used by companies like Facebook for their chat service. RabbitMQ is written in Erlang so it just makes sense to try to use Erlang.

Erlang is available when you install RabbitMQ via Homebrew using this command:

brew install rabbitmq

But if by any strange reason, you cannot get “erl” (the Erlang runtime system) to work because of this error:

-bash: /usr/local/bin/erl: No such file or directory

Just doing this would not link everything you’d need:

brew link -f erlang

This should work:

ln -s /usr/local/Cellar/erlang/R15B/lib/erlang/bin/erl /usr/local/bin/erl
ln -s /usr/local/Cellar/erlang/R15B/lib/erlang/bin/escript /usr/local/bin/escript
ln -s /usr/local/Cellar/erlang/R15B/lib/erlang/bin/run_erl /usr/local/bin/run_erl
ln -s /usr/local/Cellar/erlang/R15B/lib/erlang/bin/run_erlc /usr/local/bin/erlc

Or this:

ln -s /usr/local/Cellar/erlang/R15B02/lib/erlang/bin/erl /usr/local/bin/erl
ln -s /usr/local/Cellar/erlang/R15B02/lib/erlang/bin/escript /usr/local/bin/escript
ln -s /usr/local/Cellar/erlang/R15B02/lib/erlang/bin/run_erl /usr/local/bin/run_erl
ln -s /usr/local/Cellar/erlang/R15B02/lib/erlang/bin/run_erlc /usr/local/bin/erlc

You will need escript for compiling stuff soon.

RabbitMQ is a very significant technology. Not every application needs it but I can see some use cases for this even for small projects. Here’s a good presentation on “messaging patterns.”

Beyond Installation: How to monitor RabbitMQ

Start the server using this command:


You may browse through the API examples using curl on this link: http://localhost:55672/api/

If it asks for a user and password, enter "guest" for both. 

<strong>Start with gen_bunny for Erlang</strong>

You need to install rebar, the build-tool for Erlang before you can install <a href="https://github.com/boorad/gen_bunny" target="_blank">gen_bunny</a>. 

```ruby
git clone git://github.com/basho/rebar.git
cd rebar
./bootstrap

Now you can install and test gen_bunny:

git clone git://github.com/boorad/gen_bunny.git
cd  gen_bunny
make
make test

Hello World Example for Erlang and RabbitMQ

erl -pa `find . -type d -name ebin`
%% Load Records Used With Rabbit:
> rr("deps/rabbit_common/include/rabbit_framing.hrl").

%% Start gen_bunny as a producer using the default exchange:
> bunnyc:start_link(mq_producer,
                    {network, "localhost", 5672, {<<"guest">>, <<"guest">>}, <<"/">>},
                    {#'exchange.declare'{exchange = <<"">>, durable=true}},
                    [] ).

%% Start another gen_bunny as a producer/consumer using a named queue and exchange:
> bunnyc:start_link(mq_consumer, {network, "localhost"}, {<<"myexchange">>, <<"myqueue">>, <<"">>}, []).

%% Publish a message to "myqueue" via the default exchange:
> bunnyc:publish(mq_producer, <<"myqueue">>, <<"hello, world">>).

%% Fetch the message:
> bunnyc:get(mq_consumer, true).

{#'basic.get_ok'{delivery_tag = 1,redelivered = false,
                 exchange = <<>>,routing_key = <<"myqueue">>,
                 message_count = 0},
 {amqp_msg,#'P_basic'{content_type = undefined,
                      content_encoding = undefined,headers = undefined,
                      delivery_mode = undefined,priority = undefined,
                      correlation_id = undefined,reply_to = undefined,
                      expiration = undefined,message_id = undefined,
                      timestamp = undefined,type = undefined,user_id = undefined,
                      app_id = undefined,cluster_id = undefined},
           <<"hello, world">>}}

%% Publish a message to "myqueue" via the "myexchange" exchange:
> bunnyc:publish(mq_consumer, <<"">>, <<"hello again">>).

%% Fetch the message:
> bunnyc:get(mq_consumer, true).

{#'basic.get_ok'{delivery_tag = 2,redelivered = false,
                 exchange = <<"myexchange">>,routing_key = <<>>,
                 message_count = 0},
 {amqp_msg,#'P_basic'{content_type = undefined,
                      content_encoding = undefined,headers = undefined,
                      delivery_mode = undefined,priority = undefined,
                      correlation_id = undefined,reply_to = undefined,
                      expiration = undefined,message_id = undefined,
                      timestamp = undefined,type = undefined,user_id = undefined,
                      app_id = undefined,cluster_id = undefined},
           <<"hello again">>}}

%% Shut it down:
> bunnyc:stop(mq_consumer).
> bunnyc:stop(mq_producer).

You can see the queued messages on RabbitMQ Management via localhost:5567 when you use bunnyc:publish and see the count updated when you retrieve via bunnyc:get.

For Rubyists, it’s probably less obscure and more natural to use minion. I am just amused with Erlang language. If I like it and can see a practical use for it, expect more posts about it.