Jens Grabarske wrote:
I have a server that will use Time.repeat to send a signal to a couple
of clients every two seconds. It looks something like this:
(...)
The clients can't be trusted. It could be that they crash. So I tested
what happens when I hit CTRL-C every now and then on the client side. It
turns out that sometimes the server will tell me (I inserted some
logging stuff to see what's happening) that he threw out a misbehaving
client and just continues with sending the Messages to the other clients
(as he should). But sometimes it just blocks and doesn't do anything
anymore if I kill one of the clients.
It looks like the server isn't able to detect the failure of the client.
This is pretty common in a *real* distributed application.
The problem in your server is that the thread traversing the list of
peers can be blocked by a "bad" peer. The safe solution is to let
another thread call the peer: let the server interface each client
through a local port, with one thread forwarding message to the client.
With this technique, only the thread of the client will block:
class ServerClass from Discovery.server Time.repeat
prop locking
attr peers
...
meth register(Peer)
%% A client registers himself by sending a ticket
Client={Connection.take Peer}
S P={NewPort S}
in
thread %% forwarding messages to Client
try {ForAll S Client} catch _ then {self deregister(P)} end
end
lock peers := P|@peers end
end
meth deregister(Peer)
lock peers := {List.subtract @peers Peer} end
end
meth broadcast(Message)
{ForAll @peers proc {$ Peer} {Send Peer Message} end}
end
...
end
Be careful to keep the proxy port local to the server. Distributing
this port may bring the problem back.
Cheers,
raph
_________________________________________________________________________________
mozart-users mailing list
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users