<div dir="ltr">Ok, I can see an issue here. There's a bit of a Catch-22 where the IntialState is obtained from the driver, but we don'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) -></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> InitialState = #connection_state{username = User,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> password = Password,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> vhostpath = <<"/">>},</span><br style="font-family: courier new,monospace;"><b><span style="font-family: courier new,monospace;"> {ok, Pid} = start_internal(InitialState, "direct", ProcLink),</span><br style="font-family: courier new,monospace;">
</b><span style="font-family: courier new,monospace;"> {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) -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> InitialState = #connection_state{username = User,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> password = Password,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> serverhost = Host,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> vhostpath = VHost},</span><br style="font-family: courier new,monospace;"><b><span style="font-family: courier new,monospace;"> {ok, Pid} = start_internal(InitialState, "network", ProcLink),</span><br style="font-family: courier new,monospace;">
</b><span style="font-family: courier new,monospace;"> {Pid, network}.</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </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) -></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> DriverSpec = build_driver_spec(DriverType),</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> case ProcLink of</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> true -> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> gen_server:start_link(?MODULE, [InitialState, DriverSpec], []);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> false -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> gen_server:start(?MODULE, [InitialState, DriverSpec], [])</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> end.</span><br><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">init([InitialState, {M, F}]) -><br> State = apply(M, F, [InitialState]),<br>
{ok, State#driver_module = M}.<br> % or if we can't modify the driver state record format,<br> % 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) -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> case catch list_to_existing_atom(L) of</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> A when is_atom(A) -></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> A;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> _ -></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> list_to_atom(L)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> 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) -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> DriverModule = l2a("amqp_" ++ DriverType ++ "_driver"),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> 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;"> {DriverModule, DriverFn}.<br>
% or maybe just return a fun(X) -> 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"><<a href="mailto:rabbitmq-discuss_efine@usa.net">rabbitmq-discuss_efine@usa.net</a>></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;"> {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;"> 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"><<a href="mailto:rabbitmq-discuss_efine@usa.net" target="_blank">rabbitmq-discuss_efine@usa.net</a>></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) -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> {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;"> handle_start({ChannelNumber, OutOfBand},</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> fun Module:open_channel/3,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> fun Module:close_channel/1,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> fun Module:do/2,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> fun Module:do/3,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> 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>