3 This code implements a client for AMQP in the Erlang programming
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.
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.
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.
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.
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
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
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.
35 In order to compile/run this code you must have the following
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.
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.
51 * If you are using R12B-5 or newer:
53 Just skip to the next section.
55 * If you are using R12B-4 or older:
57 Check out eunit from their Subversion repository and build it:
59 $ svn co http://svn.process-one.net/contribs/trunk/eunit eunit
63 After this has sucessfully been built, you will need to create a symlink to
64 the eunit directory in your OTP installation directory:
66 $ cd $OTP_HOME/lib/erlang/lib
67 $ ln -sf PATH_TO_EUNIT eunit
69 where $OTP_HOME is the location of your Erlang/OTP installation.
71 Compiling the Erlang client
72 -------------------------
73 Go to the base directory of the AMQP Erlang client directory and run
76 * If you have "installed" the RabbitMQ server:
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:
83 * If you don't have the RabbitMQ server installed:
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:
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:
95 $ make BROKER_DIR=PATH_TO_THE_SERVER
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.
103 After you have done this, you can run the unit tests:
107 To get more examples of the API, look at the functions in the
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
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.
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.
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
141 $ erl -pa ebin rabbitmq_server/ebin -mnesia dir SOME_DIRECTORY \
142 -boot start_sasl -s rabbit
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
148 1> direct_client_test:test_channel_flow().
150 =INFO REPORT==== 17-Dec-2008::13:39:41 ===
151 alarm_handler: {set,{system_memory_high_watermark,[]}}
153 =INFO REPORT==== 17-Dec-2008::13:39:42 ===
154 alarm_handler: {clear,system_memory_high_watermark}
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).
163 After having booted an instance of the server with alarms handlers
164 turned on, run the following in the rabbitmq-erlang-client directory:
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]
170 Eshell V5.6.3 (abort with ^G)
171 1> test_util:channel_flow_sync(lib_amqp:start_connection("localhost")).
174 After having done this, you should see output similar to this:
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
180 To throttle the producer, go to the server shell and turn the memory
181 limit to some suitably low value:
183 2> memsup:set_sysmem_high_watermark(0.01).
186 Back in the client shell, you should see the following output:
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
192 If you now set the high water mark to say 99%, the producer should
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