<div dir="ltr">I had a surprise when trying to use the Erlang client on a node on which RabbitMQ Server was not installed.<br><br><span style="font-family: courier new,monospace;">=CRASH REPORT==== 7-Sep-2008::02:41:39 ===</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> crasher:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> pid: <0.165.0></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> registered_name: []</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> exception exit: {undef,</span><br style="font-family: courier new,monospace;">
<b style="font-family: courier new,monospace;"> [{rabbit_framing_channel,start_link,<br></b><span style="font-family: courier new,monospace;"> [#Fun<amqp_network_driver.0.106693221>,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> [<0.165.0>]]},</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> {amqp_network_driver,handshake,1},</span><br>
<br>A network client should not require server code to be installed on the same node. This is certainly true of other clients I have used. <br><br>On further investigation, I found a number of direct calls and references to an installed server:<br>
<br><span style="font-family: courier new,monospace;">amqp_channel.erl:-include_lib("rabbitmq_server/include/rabbit_framing.hrl").</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_channel.erl: rabbit_amqqueue:notify_sent(Q, ChPid),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_connection.erl:-include_lib("rabbitmq_server/include/rabbit_framing.hrl").</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_consumer.erl:-include_lib("rabbitmq_server/include/rabbit_framing.hrl").</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_network_driver.erl:-include_lib("rabbitmq_server/include/rabbit_framing.hrl").</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_network_driver.erl: FramingPid = rabbit_framing_channel:start_link(fun(X) -> X end, [Parent]),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_network_driver.erl: rabbit_writer:shutdown(WriterPid).</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_network_driver.erl: rabbit_writer:send_command(Writer, Close),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_network_driver.erl: rabbit_writer:shutdown(Writer),</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_network_driver.erl:do(Writer, Method) -> rabbit_writer:send_command(Writer, Method).</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_network_driver.erl:do(Writer, Method, Content) -> rabbit_writer:send_command(Writer, Method, Content).</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_network_driver.erl: rabbit_framing_channel:process(ChPid, Frame).</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_network_driver.erl: response = rabbit_binary_generator:generate_table(LoginTable),</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_network_driver.erl: rabbit_writer:start(Sock, Channel, ?FRAME_MIN_SIZE).</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_network_driver.erl: rabbit_heartbeat:start_heartbeat(Sock, Heartbeat),</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_network_driver.erl: FramingPid = rabbit_framing_channel:start_link(fun(X) -> link(X), X end, [ChannelPid]),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_network_driver.erl: case rabbit_reader:analyze_frame(Type, Payload) of</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_network_driver.erl: rabbit_misc:die(frame_error);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_network_driver.erl: rabbit_misc:die(frame_error);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_rpc_client.erl:-include_lib("rabbitmq_server/include/rabbit_framing.hrl").</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_rpc_client.erl: content_type = ContentType} = rabbit_framing:decode_properties(ClassId, PropertiesBin),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_rpc_handler.erl:-include_lib("rabbitmq_server/include/rabbit_framing.hrl").</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_rpc_handler.erl: = rabbit_framing:decode_properties(ClassId, PropertiesBin),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">amqp_rpc_util.erl:-include_lib("rabbitmq_server/include/rabbit_framing.hrl").</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">amqp_util.erl:-include_lib("rabbitmq_server/include/rabbit_framing.hrl").</span><br>
<br>I left out the direct driver modules because by definition they need to be on the same node.<br><br>I respectfully suggest that the above RabbitMQ server modules, and their dependencies, be bundled with the Erlang client. Ideally, I would think it would be best perhaps to put them a separate Erlang library application (maybe "rabbitmq_common") that is used both by the server and the Erlang client.<br>
<br>In addition to that, the include_lib("rabbitmq_server/include/xxx.hrl") statements prevent one from even compiling the client unless the server is installed and this should be changed to use the common library app. I was forced to copy the include files and make a dummy rabbitmq_server application to be able to compile the client on a different node to the server.<br>
<br>Regards,<br>Edwin Fine<br><br></div>