[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