Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Erlang
branch: bug19847

This branch is even with rabbitmq:bug19847

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
include
src
tests
.hgignore
Makefile
README

README

AMQP client for Erlang
======================
This code implements a client for AMQP in the Erlang programming
language.

This client offers both a networked version that uses standard
TCP-based AMQP framing and a direct client that uses native Erlang
message passing to a RabbitMQ broker.

The API exposed to the user is common to both clients, so each version
can be used interchangeably without having to modify any client code.

The TCP networked client has been tested with RabbitMQ server 1.4.0,
but should theoretically work with any 0-8 compliant AMQP server.

The direct client is bound to an 0-8 compliant broker using native
Erlang message passing, which in the absence of an alternative Erlang
AMQP implementation means that it only works with RabbitMQ.

It does however provide a level of abstraction above the internal
server API of RabbitMQ, meaning that you can write client code in
Erlang and still remain isolated from any API changes in the
underlying broker.

It also provides a client-orientated API into RabbitMQ, allowing the
user to reuse AMQP knowledge gained by using AMQP clients in other
languages.

The advantage of the direct client is that it eliminates the network
overhead as well as the marshaling to and from the AMQP wire format,
so that neither side has to decode or encode any AMQP frames.

Prerequisites
-------------
In order to compile/run this code you must have the following
installed:

- Erlang/OTP, R11B-5 or later, http://www.erlang.org/download.html
- The RabbitMQ server, 93cc2ca0ba62 or later
- Eunit, the Erlang unit testing framework - currently the whole build process
  depends on eunit because all of the modules are compiled together.
  A future version of the build process could remove this dependency when you
  only want to compile the core libraries.

Getting Eunit
-------------
The test suite uses eunit which is either available bundled with OTP from
release R12B-5 onwards or as a separate download that you will need to build
yourself if you are using an older version of Erlang.

* If you are using R12B-5 or newer:

Just skip to the next section.

* If you are using R12B-4 or older:

Check out eunit from their Subversion repository and build it:

    $ svn co http://svn.process-one.net/contribs/trunk/eunit eunit
    $ cd eunit
    $ make

After this has sucessfully been built, you will need to create a symlink to
the eunit directory in your OTP installation directory:

    $ cd $OTP_HOME/lib/erlang/lib
    $ ln -sf PATH_TO_EUNIT eunit

where $OTP_HOME is the location of your Erlang/OTP installation.

Compiling the Erlang client
-------------------------
Go to the base directory of the AMQP Erlang client directory and run
'make'.

* If you have "installed" the RabbitMQ server:

You will have a symlink to the rabbitmq-server directory in your OTP
directory, so all you have to do is to run make:

    $ make

* If you don't have the RabbitMQ server installed:

You will need to get a copy of the server in order to be able to use it's
header files and runtime libraries. A good place to put this is in the sibling
directory to the Erlang client, which is the default that Makefile expects.
In this case, you can just run make:

    $ make

If the source tree for the server is not in the sibling directory, you will
need to specify the path to this directory:

    $ make BROKER_DIR=PATH_TO_THE_SERVER

Running the network client tests
--------------------------------
In order to run the network client, you need to run the RabbitMQ
server in a separate Erlang process (or use any other compliant AMQP
server). Start your server as usual.

After you have done this, you can run the unit tests:

    $ make test_network

To get more examples of the API, look at the functions in the
test_util module.

Running the direct client tests
-------------------------------
The direct client has to be run in the same Erlang VM instance as the
RabbitMQ server. In order to use the makefile to run the direct client tests,
you will need to shutdown any other running instance of RabbitMQ that you may
have on your machine. This is because the Makefile target for running the
direct tests boots its own instance of RabbitMQ. To run these tests, use the
following target.

    $ make test_direct

Running the channel flow tests
------------------------------
There are two tests for producer control flow. The first is a unit
test that asserts the reception of the correct chain of commands in
conjunction with a direct manipulation of the high water mark. The
second test does not make any assertion about the behavior of the
server but it does produce output that demonstrates that the client
library is indeed notifying higher level application code that flow
control has been activated or deactivated.

Both tests require that the memory alarms are turned on in the
server. By default they are turned off. To turn them on, set the
memory_alarms flag in the rabbit.app config file.

Because the unit test accesses memsup directly, it needs to use the
direct API and hence needs to run in the same VM as the server. To do
this from the rabbitmq-erlang-client directory, run the following
commmand (where SOME_DIRECTORY is some directory where you want mnesia
to log its files):

    $ erl -pa ebin rabbitmq_server/ebin -mnesia dir SOME_DIRECTORY \
      -boot start_sasl -s rabbit
      
When that has booted, you need to wait one minute for the memory
alarms to become active. After that, you can run the following from
the Erlang shell:

    1> direct_client_test:test_channel_flow().

    =INFO REPORT==== 17-Dec-2008::13:39:41 ===
    alarm_handler: {set,{system_memory_high_watermark,[]}}

    =INFO REPORT==== 17-Dec-2008::13:39:42 ===
    alarm_handler: {clear,system_memory_high_watermark}
    ok
    2>

The non-unit test can be run in separate VM, because it uses the
network client driver. Whilst it can be run using the direct client,
it produces log output which makes it difficult to enter in commands
interactively (which you need to do to see the throttling).

After having booted an instance of the server with alarms handlers
turned on, run the following in the rabbitmq-erlang-client directory:

    rabbitmq-erlang-client $ erl -pa rabbitmq_server/ebin/ ebin/
    Erlang (BEAM) emulator version 5.6.3 [source] [smp:2] \
    [async-threads:0][kernel-poll:false]

    Eshell V5.6.3  (abort with ^G)
    1> test_util:channel_flow_sync(lib_amqp:start_connection("localhost")).
    {<0.39.0>,<0.40.0>}

After having done this, you should see output similar to this:
    
    Producer (<0.39.0>) has sent about 0 messages since it started
    Producer (<0.39.0>) has sent about 5000 messages since it started
    Producer (<0.39.0>) has sent about 10000 messages since it started
      
To throttle the producer, go to the server shell and turn the memory
limit to some suitably low value:
    
    2> memsup:set_sysmem_high_watermark(0.01).
    ok
    
Back in the client shell, you should see the following output:
    .....
    Producer (<0.39.0>) has sent about 235000 messages since it started
    Producer throttling ON
    Producer (<0.39.0>) is blocked, will go to sleep.....ZZZ
    
If you now set the high water mark to say 99%, the producer should
wake up again:

    Producer throttling OFF, waking up producer (<0.39.0>)
    Producer (<0.39.0>) has woken up :-)
    Producer (<0.39.0>) has sent about 240000 messages since it started
    .....
Something went wrong with that request. Please try again.