spread erlang driver

Serge Aleynikov serge@REDACTED
Fri Jan 28 05:04:35 CET 2005


Hi,

I recently downloaded a spread_drv project from jungerl and tried to 
build a small app using this library.

http://cvs.sourceforge.net/viewcvs.py/jungerl/jungerl/lib/spread_drv/

I would appreciate it if you could clarify one issue related to the 
design of the driver.

It appears that the gen_server (spread.erl) maintains a list of 
subscriber PIDs to messages received by a spread group in its internal 
state (using ets storage).  I have the following implementation.  A 
server process subscribes itself to a group "test" using 
spread:subscribe(), and when the group receives a message, it gets 
dispatched to the server in handle_info() callback.  The server 
processes the message and sends a response back to the client's private 
group:

{ok, Pid} = spread:start_link("4803@REDACTED", "test", 0, 1),
{ok, _}   = spread:subscribe(Pid, "test"),
...
handle_info(..., Sender, ..., Msg) ->
    % when a regular message is received, process it and reply to sender
    Reply = process_message(Msg),
    spread:multicast(SpreadPid, binary_to_list(Sender), 1, Reply).
...

A client process needs to send a message to the "test" group in order to 
get a response from the server, and waits for a response in the 
following way:

{ok, Pid} = spread:start_link("4803@REDACTED", "client", 0, 0),
spread:multicast(Pid, "test", 1, <<"Some message">>),
receive
Response ->
    do_something(Response);
after ?Timeout ->
    timeout
end.

I encountered the problem that the client's receive always times out.
It looks like any message unicasted to a private group of a process (in 
this case "client" is the private group identifying the client) doesn't 
get dispatched to the process's mailbox, and can only be retrieved from 
spread by using the spread:rec() function.  So the following 
implementation works correctly:

{ok, Pid} = spread:start_link("4803@REDACTED", "client", 0, 0),
spread:multicast(Pid, "test", 1, <<"Some message">>),
Reply = spread:rec(Pid, "#client#localhost").

I traced this problem to the fact that a process always needs to 
subscribe itself to a spread group (using spread:subscribe(Pid, Group)) 
in order to receive messages through

receive
...
end.

However, it is not possible for the process to subscribe to its own 
private group.  An attempt to do so will be rejected by spread, and 
therefore its Pid will not get added to the spread gen_server's internal 
state ets.  As a result the process will never receive a message in its 
mailbox, and the message will always need to be fetched using a 
synchronous spread:rec() call.

I wonder if this was an oversight or a design decision.

Also, a side note is that the private group's name (returned by 
spread_drv:sp_connect()) is not exported by any function, and therefore 
the client's call above:

spread:rec(Pid, PrivateGroup)

Needs to figure out its own PrivateGroup.  I ended up extending 
spread.erl by adding get_private_group/1 to accomplish this task.

Is anybody using this spread_drv interface in any active project?

Thank you,

Serge



More information about the erlang-questions mailing list