DRb::DRbObject.alive?

B

Benoit Daloze

[Note: parts of this message were removed to make it a legal post.]

Hi,

I found a feature that seem to be missing to me in DRb.

I'm just creating a chat with a client and a server, using only DRb to
interact between them.

My problem is I didn't found a nice way to verify if a client is alive.
I would like to be able to update my clients' list, but I need to know if
they are alive.

Currently, I'm getting around with catching the Exception DRb::DRbConnError,
but that looks really ugly:
@clients.each { |c|
begin
c.respond_to?:)some_method_defined_in_client) #Trying to use any method
of c will raise the exception (except if not defined)
rescue DRb::DRbConnError
@clients.delete(c)
end
}

Using Exceptions would be meaningful when I try to send(it would raise the
exception if I call #send), but then I would have to manage Exceptions
everywhere.

The method alive? is defined for the DRbServer and DRbTCPSocket, but not for
DRbObject! (in fact if the Client just got disconnected, alive? will still
return true)

Does somebody already met this? (And does somebody knows what DRb is?^^
Please have a look it's pretty cool, but the documentation could even be
better...)

Benoit
 
R

Robert Klemme

I found a feature that seem to be missing to me in DRb.

I'm just creating a chat with a client and a server, using only DRb to
interact between them.

My problem is I didn't found a nice way to verify if a client is alive.
I would like to be able to update my clients' list, but I need to know if
they are alive.

Currently, I'm getting around with catching the Exception DRb::DRbConnError,
but that looks really ugly:
@clients.each { |c|
begin
c.respond_to?:)some_method_defined_in_client) #Trying to use any method
of c will raise the exception (except if not defined)
rescue DRb::DRbConnError
@clients.delete(c)
end
}

Using Exceptions would be meaningful when I try to send(it would raise the
exception if I call #send), but then I would have to manage Exceptions
everywhere.

Well, but this is the usual approach.
The method alive? is defined for the DRbServer and DRbTCPSocket, but not for
DRbObject! (in fact if the Client just got disconnected, alive? will still
return true)

It should not be too difficult to add method alive? to DRbUndumped.
However, there is a more fundamental problem that cannot be solved: even
if you have method alive? and it is working properly what does it tell
you? It tells you that the object was alive when you invoked that
method. You have no guarantees that it will be alive when you make the
next remote method call. Hence you need to handle exceptions anyway.
Now you have exception handling plus additional code that checks
liveness beforehand. Your code is complexer and slower.
Does somebody already met this?

This is a common issue people stumble over all the time (typically with
things that involve interprocess communication such as for database
connections and the like). The issue is always the same: you do not
gain anything with this method because you have to deal with failure anyway.

Kind regards

robert
 
B

Benoit Daloze

[Note: parts of this message were removed to make it a legal post.]

Yeah, you're right.

So here's how I did to not duplicate the code:

def try_on_clients
@clients.each { |client|
begin
yield client
rescue DRb::DRbConnError
del_drb_client(client)
end
}
end

def receive_message(msg)
try_on_clients { |client| client.show_message(msg) }
end

That looks already more beautiful, and doesn't spend time looking if alive.
Anyway, it's a little too bad for the client, because any connection error
will drop him away, but he can reconnect easily.

Regards,
Benoit
 
R

Robert Klemme

2009/11/25 Benoit Daloze said:
Yeah, you're right.

So here's how I did to not duplicate the code:

=A0 =A0 def try_on_clients
=A0 =A0 =A0 [email protected] { |client|
=A0 =A0 =A0 =A0 =A0 =A0begin
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0yield client
=A0 =A0 =A0 =A0 =A0 =A0rescue DRb::DRbConnError
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0del_drb_client(client)
=A0 =A0 =A0 =A0 =A0 =A0end
=A0 =A0 =A0 =A0}
=A0 =A0end

=A0 =A0def receive_message(msg)
=A0 =A0 =A0 =A0try_on_clients { |client| client.show_message(msg) }
=A0 =A0end

That looks already more beautiful, and doesn't spend time looking if aliv= e.
Anyway, it's a little too bad for the client, because any connection erro= r
will drop him away, but he can reconnect easily.

Well, you could place them in a closed list (or queue) or even return
the array of closed / removed clients.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top