[rabbitmq-discuss] [BUG] Erlang RabbitMQ client requires installed server code
Edwin Fine
rabbitmq-discuss_efine at usa.net
Mon Sep 8 01:40:35 BST 2008
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 :).
So I have another suggestion. By the principle of convention over
configuration, I present some code, unfortunately a bit long winded but
necessary.
%% Starts a direct connection to the Rabbit AMQP server, assuming that
%% the server is running in the same process space.
start(User,Password,ProcLink) when is_boolean(ProcLink) ->
InitialState = #connection_state{username = User,
password = Password,
vhostpath = <<"/">>},
* {ok, Pid} = start_internal(InitialState, "direct", ProcLink),
* {Pid, direct};
%% Starts a networked conection to a remote AMQP server.
start(User,Password,Host,VHost,ProcLink) ->
InitialState = #connection_state{username = User,
password = Password,
serverhost = Host,
vhostpath = VHost},
* {ok, Pid} = start_internal(InitialState, "network", ProcLink),
* {Pid, network}.
start_internal(InitialState, DriverType, ProcLink) when is_list(DriverType)
->
DriverSpec = build_driver_spec(DriverType),
case ProcLink of
true ->
gen_server:start_link(?MODULE, [InitialState, DriverSpec], []);
false ->
gen_server:start(?MODULE, [InitialState, DriverSpec], [])
end.
init([InitialState, {M, F}]) ->
State = apply(M, F, [InitialState]),
{ok, State#driver_module = M}.
% or if we can't modify the driver state record format,
% we could piggyback it, e.g. #mystate{drv_state = State, drv_module =
Module}
l2a(L) ->
case catch list_to_existing_atom(L) of
A when is_atom(A) ->
A;
_ ->
list_to_atom(L)
end.
build_driver_spec(DriverType) ->
DriverModule = l2a("amqp_" ++ DriverType ++ "_driver"),
DriverFn = handshake,
{DriverModule, DriverFn}.
% or maybe just return a fun(X) -> DriverModule:handshake/1, but is that
legal?
The rest follows as before.
Thoughts?
On Sun, Sep 7, 2008 at 8:13 PM, Edwin Fine
<rabbitmq-discuss_efine at usa.net>wrote:
> Hm, I made a mistake in my excitement :)
>
> {ok, Module} = proplists:get_value(Flavor, State#state.flavor_module),
>
> should be
>
> Module = proplists:get_value(Flavor, State#state.flavor_modules),
>
> where flavor_modules would contain something like [{direct,
> amqp_direct_driver}, {network, amqp_network_driver}, {whatever,
> amqp_whatever_driver}].
>
>
> On Sun, Sep 7, 2008 at 8:06 PM, Edwin Fine <rabbitmq-discuss_efine at usa.net
> > wrote:
>
>> 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.
>>
>> %% Starts a new channel. Flavor is direct or network. flavor_module is set
>> up to be
>> %% one of amqp_direct_driver or amqp_network_driver (or, some other driver
>> - e.g. future amqp_wmq_driver)
>> handle_call({Flavor, ChannelNumber, OutOfBand}, From, State) ->
>> {ok, Module} = proplists:get_value(Flavor, State#state.flavor_module),
>> handle_start({ChannelNumber, OutOfBand},
>> fun Module:open_channel/3,
>> fun Module:close_channel/1,
>> fun Module:do/2,
>> fun Module:do/3,
>> State);
>>
>> What do you think?
>>
>> Regards,
>> Edwin
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20080907/a9042158/attachment.htm
More information about the rabbitmq-discuss
mailing list