views:

477

answers:

1

I have a server which is using the remote actors framework to communicate with multiple clients. As mentioned in this question, I am having trouble keeping track of when a client disappears. Hence my server is still attempting to send messages to non-existent clients.

  • Is this a problem? (I don't see any exceptions being thrown - but I assume there'll be memory issues if my server is long-lived)
  • How can I detect that a message is being sent to a client no longer listening? (If I want to implement some kind of connection clean-up)
+1  A: 

OK, I'll risk something here.

disclaimer: despite what you will read below, you may want to start here.

I'm not familiar with scala, but it uses similar principles to Erlang's and I feel somewhat comfortable there. The thing that is confusing me about your question however, has little to do with this. But more with the client-server relationship you seem to be establishing.

By definition, a server will not keep sending messages to the client unless it receives a request. That is, the server actor class should be built (not necessarily always) around case statements that check the received message and act accordingly. So, in this context the client is existing and the server shouldn't worry about it and instead send its reply message normally, because the client just made its presence aware with a request.

So if your server is still trying to send messages to clients, despite these having been closed down, seems to me it is trying to send messages despite having received no request. This is fundamentally wrong in the context of a client-server relationship. The server should only react on request. Otherwise it is taking on the role of the client.

In any case, you can (and you should) define an end to any client-server conversation. This will help release resources and end established connections. For that effect:

  1. Your client actor should send a stop message to the server and terminate its execution with whatever exit function scala has implemented for the actor class.

  2. On receiving a stop message, the server actor should not reply to the client. Instead it should do its cleanup (if any) and terminate execution similarly to the client actor.

This way you ensure proper termination of all actors involved and a correct release of resources.

I hope this helped somehow. Unfortunately I'm not familiar with scala itself. Otherwise I could bring in some code. But the above link should help, hopefully.

Krugar
I'm afraid this approach just does not work. You cannot guarantee that the *stop* method is sent to the server and when this happens, the mailbox of the server-side channel *proxy* for the client actor fills up and eventually the server crashes as it goes out of memory. I've found the only mechanism is for clients to renew a "lease" on a timer: the server periodically checks the leases and any expired ones are thrown away
oxbow_lakes
+1. I agree, oxbow. But I'd still code that around a stop message for normal, faster termination on those cases the message is received.
Krugar