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

Reply via email to