<div dir="ltr">Ok, I can see an issue here. There&#39;s a bit of a Catch-22 where the IntialState is obtained from the driver, but we don&#39;t know which driver to get it from because the drive name has to be in the state :).<br>
<br>So I have another suggestion. By the principle of convention over configuration, I present some code, unfortunately a bit long winded but necessary.<br><br><span style="font-family: courier new,monospace;">%% Starts a direct connection to the Rabbit AMQP server, assuming that</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">%% the server is running in the same process space.</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">start(User,Password,ProcLink) when is_boolean(ProcLink) -&gt;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; InitialState = #connection_state{username = User,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password = Password,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vhostpath = &lt;&lt;&quot;/&quot;&gt;&gt;},</span><br style="font-family: courier new,monospace;"><b><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; {ok, Pid} = start_internal(InitialState, &quot;direct&quot;, ProcLink),</span><br style="font-family: courier new,monospace;">
</b><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; {Pid, direct};</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">%% Starts a networked conection to a remote AMQP server.</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">start(User,Password,Host,VHost,ProcLink) -&gt;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; InitialState = #connection_state{username = User,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password = Password,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serverhost = Host,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vhostpath = VHost},</span><br style="font-family: courier new,monospace;"><b><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; {ok, Pid} = start_internal(InitialState, &quot;network&quot;, ProcLink),</span><br style="font-family: courier new,monospace;">
</b><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; {Pid, network}.</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">start_internal(InitialState, DriverType, ProcLink) when is_list(DriverType) -&gt;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; DriverSpec = build_driver_spec(DriverType),</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; case ProcLink of</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; true -&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gen_server:start_link(?MODULE, [InitialState, DriverSpec], []);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; false -&gt;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gen_server:start(?MODULE, [InitialState, DriverSpec], [])</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; end.</span><br><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">init([InitialState, {M, F}]) -&gt;<br>&nbsp;&nbsp;&nbsp; State = apply(M, F, [InitialState]),<br>
&nbsp;&nbsp;&nbsp; {ok, State#driver_module = M}.<br>&nbsp;&nbsp;&nbsp; % or if we can&#39;t modify the driver state record format,<br>&nbsp;&nbsp;&nbsp; % we could piggyback it, e.g. #mystate{drv_state = State, drv_module = Module}<br></span><span style="font-family: courier new,monospace;"><br>
l2a(L) -&gt;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; case catch list_to_existing_atom(L) of</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A when is_atom(A) -&gt;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ -&gt;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_to_atom(L)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; end.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">build_driver_spec(DriverType) -&gt;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; DriverModule = l2a(&quot;amqp_&quot; ++ DriverType ++ &quot;_driver&quot;),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; DriverFn = handshake,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; {DriverModule, DriverFn}.<br>

&nbsp;&nbsp;&nbsp; % or maybe just return a fun(X) -&gt; DriverModule:handshake/1, but is that legal?<br>
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"></span><br>The rest follows as before.<br><br>Thoughts?<br><br><br><div class="gmail_quote">On Sun, Sep 7, 2008 at 8:13 PM, Edwin Fine <span dir="ltr">&lt;<a href="mailto:rabbitmq-discuss_efine@usa.net">rabbitmq-discuss_efine@usa.net</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div dir="ltr">Hm, I made a mistake in my excitement :)<div class="Ih2E3d"><br><br><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; {ok, Module} = proplists:get_value(Flavor, State#state.flavor_module),</span><br style="font-family: courier new,monospace;">


<span style="font-family: courier new,monospace;"></span><br></div>should be<br><br><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; Module = proplists:get_value(Flavor, State#state.flavor_modules),</span><br style="font-family: courier new,monospace;">


<span style="font-family: courier new,monospace;"></span><br>where flavor_modules would contain something like [{direct, amqp_direct_driver}, {network, amqp_network_driver}, {whatever, amqp_whatever_driver}].<div><div></div>
<div class="Wj3C7c"><br><br><div class="gmail_quote">
On Sun, Sep 7, 2008 at 8:06 PM, Edwin Fine <span dir="ltr">&lt;<a href="mailto:rabbitmq-discuss_efine@usa.net" target="_blank">rabbitmq-discuss_efine@usa.net</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<div dir="ltr">Let me make a constructive suggestion. By using the configuration, we could avoid the compile-time dependency on either of those modules, and at the same time we could make amqp_connection more flexible.<br>


<br><span style="font-family: courier new,monospace;">%% Starts a new channel. Flavor is direct or network. flavor_module is set up to be</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">%% one of amqp_direct_driver or amqp_network_driver (or, some other driver - e.g. future amqp_wmq_driver)</span><br style="font-family: courier new,monospace;">


<span style="font-family: courier new,monospace;">handle_call({Flavor, ChannelNumber, OutOfBand}, From, State) -&gt;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; {ok, Module} = proplists:get_value(Flavor, State#state.flavor_module),</span><br style="font-family: courier new,monospace;">


<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; handle_start({ChannelNumber, OutOfBand},</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fun Module:open_channel/3,</span><br style="font-family: courier new,monospace;">


<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fun Module:close_channel/1,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fun Module:do/2,</span><br style="font-family: courier new,monospace;">


<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fun Module:do/3,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; State);</span><br>


<br>What do you think?<br><br>Regards,<br>Edwin<br></div>
</blockquote></div><br></div></div></div>
</blockquote></div><br></div>