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