README
author Matthias Radestock <matthias@lshift.net>
Thu Jan 08 14:41:54 2009 +0000 (2009-01-08)
changeset 205 3c6f7b5e67ae
parent 181 45b1be4a9479
child 282 537cb2754144
permissions -rw-r--r--
merge bug19964 into default
     1 AMQP client for Erlang
     2 ======================
     3 This code implements a client for AMQP in the Erlang programming
     4 language.
     5 
     6 This client offers both a networked version that uses standard
     7 TCP-based AMQP framing and a direct client that uses native Erlang
     8 message passing to a RabbitMQ broker.
     9 
    10 The API exposed to the user is common to both clients, so each version
    11 can be used interchangeably without having to modify any client code.
    12 
    13 The TCP networked client has been tested with RabbitMQ server 1.4.0,
    14 but should theoretically work with any 0-8 compliant AMQP server.
    15 
    16 The direct client is bound to an 0-8 compliant broker using native
    17 Erlang message passing, which in the absence of an alternative Erlang
    18 AMQP implementation means that it only works with RabbitMQ.
    19 
    20 It does however provide a level of abstraction above the internal
    21 server API of RabbitMQ, meaning that you can write client code in
    22 Erlang and still remain isolated from any API changes in the
    23 underlying broker.
    24 
    25 It also provides a client-orientated API into RabbitMQ, allowing the
    26 user to reuse AMQP knowledge gained by using AMQP clients in other
    27 languages.
    28 
    29 The advantage of the direct client is that it eliminates the network
    30 overhead as well as the marshaling to and from the AMQP wire format,
    31 so that neither side has to decode or encode any AMQP frames.
    32 
    33 Prerequisites
    34 -------------
    35 In order to compile/run this code you must have the following
    36 installed:
    37 
    38 - Erlang/OTP, R11B-5 or later, http://www.erlang.org/download.html
    39 - The RabbitMQ server, 93cc2ca0ba62 or later
    40 - Eunit, the Erlang unit testing framework - currently the whole build process
    41   depends on eunit because all of the modules are compiled together.
    42   A future version of the build process could remove this dependency when you
    43   only want to compile the core libraries.
    44 
    45 Getting Eunit
    46 -------------
    47 The test suite uses eunit which is either available bundled with OTP from
    48 release R12B-5 onwards or as a separate download that you will need to build
    49 yourself if you are using an older version of Erlang.
    50 
    51 * If you are using R12B-5 or newer:
    52 
    53 Just skip to the next section.
    54 
    55 * If you are using R12B-4 or older:
    56 
    57 Check out eunit from their Subversion repository and build it:
    58 
    59     $ svn co http://svn.process-one.net/contribs/trunk/eunit eunit
    60     $ cd eunit
    61     $ make
    62 
    63 After this has sucessfully been built, you will need to create a symlink to
    64 the eunit directory in your OTP installation directory:
    65 
    66     $ cd $OTP_HOME/lib/erlang/lib
    67     $ ln -sf PATH_TO_EUNIT eunit
    68 
    69 where $OTP_HOME is the location of your Erlang/OTP installation.
    70 
    71 Compiling the Erlang client
    72 -------------------------
    73 Go to the base directory of the AMQP Erlang client directory and run
    74 'make'.
    75 
    76 * If you have "installed" the RabbitMQ server:
    77 
    78 You will have a symlink to the rabbitmq-server directory in your OTP
    79 directory, so all you have to do is to run make:
    80 
    81     $ make
    82 
    83 * If you don't have the RabbitMQ server installed:
    84 
    85 You will need to get a copy of the server in order to be able to use it's
    86 header files and runtime libraries. A good place to put this is in the sibling
    87 directory to the Erlang client, which is the default that Makefile expects.
    88 In this case, you can just run make:
    89 
    90     $ make
    91 
    92 If the source tree for the server is not in the sibling directory, you will
    93 need to specify the path to this directory:
    94 
    95     $ make BROKER_DIR=PATH_TO_THE_SERVER
    96 
    97 Running the network client tests
    98 --------------------------------
    99 In order to run the network client, you need to run the RabbitMQ
   100 server in a separate Erlang process (or use any other compliant AMQP
   101 server). Start your server as usual.
   102 
   103 After you have done this, you can run the unit tests:
   104 
   105     $ make test_network
   106 
   107 To get more examples of the API, look at the functions in the
   108 test_util module.
   109 
   110 Running the direct client tests
   111 -------------------------------
   112 The direct client has to be run in the same Erlang VM instance as the
   113 RabbitMQ server. In order to use the makefile to run the direct client tests,
   114 you will need to shutdown any other running instance of RabbitMQ that you may
   115 have on your machine. This is because the Makefile target for running the
   116 direct tests boots its own instance of RabbitMQ. To run these tests, use the
   117 following target.
   118 
   119     $ make test_direct
   120 
   121 Running the channel flow tests
   122 ------------------------------
   123 There are two tests for producer control flow. The first is a unit
   124 test that asserts the reception of the correct chain of commands in
   125 conjunction with a direct manipulation of the high water mark. The
   126 second test does not make any assertion about the behavior of the
   127 server but it does produce output that demonstrates that the client
   128 library is indeed notifying higher level application code that flow
   129 control has been activated or deactivated.
   130 
   131 Both tests require that the memory alarms are turned on in the
   132 server. By default they are turned off. To turn them on, set the
   133 memory_alarms flag in the rabbit.app config file.
   134 
   135 Because the unit test accesses memsup directly, it needs to use the
   136 direct API and hence needs to run in the same VM as the server. To do
   137 this from the rabbitmq-erlang-client directory, run the following
   138 commmand (where SOME_DIRECTORY is some directory where you want mnesia
   139 to log its files):
   140 
   141     $ erl -pa ebin rabbitmq_server/ebin -mnesia dir SOME_DIRECTORY \
   142       -boot start_sasl -s rabbit
   143       
   144 When that has booted, you need to wait one minute for the memory
   145 alarms to become active. After that, you can run the following from
   146 the Erlang shell:
   147 
   148     1> direct_client_test:test_channel_flow().
   149 
   150     =INFO REPORT==== 17-Dec-2008::13:39:41 ===
   151     alarm_handler: {set,{system_memory_high_watermark,[]}}
   152 
   153     =INFO REPORT==== 17-Dec-2008::13:39:42 ===
   154     alarm_handler: {clear,system_memory_high_watermark}
   155     ok
   156     2>
   157 
   158 The non-unit test can be run in separate VM, because it uses the
   159 network client driver. Whilst it can be run using the direct client,
   160 it produces log output which makes it difficult to enter in commands
   161 interactively (which you need to do to see the throttling).
   162 
   163 After having booted an instance of the server with alarms handlers
   164 turned on, run the following in the rabbitmq-erlang-client directory:
   165 
   166     rabbitmq-erlang-client $ erl -pa rabbitmq_server/ebin/ ebin/
   167     Erlang (BEAM) emulator version 5.6.3 [source] [smp:2] \
   168     [async-threads:0][kernel-poll:false]
   169 
   170     Eshell V5.6.3  (abort with ^G)
   171     1> test_util:channel_flow_sync(lib_amqp:start_connection("localhost")).
   172     {<0.39.0>,<0.40.0>}
   173 
   174 After having done this, you should see output similar to this:
   175     
   176     Producer (<0.39.0>) has sent about 0 messages since it started
   177     Producer (<0.39.0>) has sent about 5000 messages since it started
   178     Producer (<0.39.0>) has sent about 10000 messages since it started
   179       
   180 To throttle the producer, go to the server shell and turn the memory
   181 limit to some suitably low value:
   182     
   183     2> memsup:set_sysmem_high_watermark(0.01).
   184     ok
   185     
   186 Back in the client shell, you should see the following output:
   187     .....
   188     Producer (<0.39.0>) has sent about 235000 messages since it started
   189     Producer throttling ON
   190     Producer (<0.39.0>) is blocked, will go to sleep.....ZZZ
   191     
   192 If you now set the high water mark to say 99%, the producer should
   193 wake up again:
   194 
   195     Producer throttling OFF, waking up producer (<0.39.0>)
   196     Producer (<0.39.0>) has woken up :-)
   197     Producer (<0.39.0>) has sent about 240000 messages since it started
   198     .....