Drb graceful shutdown

H

Han Holl

Hello,

As far as I can see from the source, there is no other way to end the connection
to a remote object than through a raised exception.
Of course, most of the time this will be a connect error because the client
just disconnects, but using ethereal I can see that the server still writes a
complete backtrace to the socket.
Wouldn't it be desirable to have a more elegant way of disconnecting, or is there
one that I just didn't see ?
This is drb-2.0.4.

Cheers,

Han Holl
 
E

Eric Hodel

--gWRamliw218YCZO9
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
As far as I can see from the source, there is no other way to end the
connection to a remote object than through a raised exception. Of
course, most of the time this will be a connect error because the
client just disconnects, but using ethereal I can see that the server
still writes a complete backtrace to the socket. Wouldn't it be
desirable to have a more elegant way of disconnecting, or is there one
that I just didn't see ?

Nope! There's no way to gracefully disconnect a DRb session, since you
may not know what all is still "alive" and being shared between servers.
Also note that there are not strict "clients" or "servers" in DRb, since
an object may be shared both ways. At some time the "server" may try to
access a resource from the "client", even when it is long-gone, either
from the client disconnecting, or from the resource being
garbage-collected on the client side.

--=20
Eric Hodel - (e-mail address removed) - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04


--gWRamliw218YCZO9
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (FreeBSD)

iD8DBQFA01ATMypVHHlsnwQRAgxQAKCxyIBIqIJ/ext0bfkKNEcEiyOd9gCgnPbB
GfR6nALIxN/X9K8MANrZoEg=
=iwxn
-----END PGP SIGNATURE-----

--gWRamliw218YCZO9--
 
E

Eric Hodel

--oJAv8lSwuaQsYd0G
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
So how do you gracefully shutdown your application?

You must be careful when designing an application that uses DRb so that
you know where remote references are created and ensure that they are
alive when you expect them to be alive, and die when you expect them to
die.

This is an example of what not to do:

class RemoteObj
include DRbUndumped
...
end

class Server
def get_resource
return RemoteObj.new
end
end

DRb.start_service nil, Server.new

In this case the server will return to the client a resource that will
dissappear after the GC gets run. DRb has a mechanism to handle this,
id conversion, so that remotely referenced objects have a chance to stay
"alive" longer than the GC would let them. Look at DRb::TimerIdConv
compared to DRb::DRbIdConv. (For those of you not following along at
home, TimerIdConv uses a time-since-last-access to recycle remote
objects, while DRbIdConv uses ObjectSpace to retrieve objects.)

You could extend DRb::TimerIdConv to delay shutting down the DRb server
until after all remote objects expire. Unfortunately, this brings you
to the choice of either waiting a long time to complete application
shutdown, or shutting down before the client processes are done with the
references.

--=20
Eric Hodel - (e-mail address removed) - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04


--oJAv8lSwuaQsYd0G
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (FreeBSD)

iD8DBQFA02a4MypVHHlsnwQRApX9AKC4PbzRf5CPy6eywy9czhrXs5btTgCfR8Jp
4XD3nSNNo7MbHK56a4PCm10=
=MA2j
-----END PGP SIGNATURE-----

--oJAv8lSwuaQsYd0G--
 
H

Han Holl

Eric Hodel said:
This is an example of what not to do:

class RemoteObj
include DRbUndumped
...
end

class Server
def get resource
return RemoteObj.new
end
end

DRb.start service nil, Server.new

In this case the server will return to the client a resource that will
dissappear after the GC gets run. DRb has a mechanism to handle this,
id conversion, so that remotely referenced objects have a chance to stay
"alive" longer than the GC would let them. Look at DRb::TimerIdConv
compared to DRb::DRbIdConv. (For those of you not following along at
home, TimerIdConv uses a time-since-last-access to recycle remote
objects, while DRbIdConv uses ObjectSpace to retrieve objects.)

You could extend DRb::TimerIdConv to delay shutting down the DRb server
until after all remote objects expire. Unfortunately, this brings you
to the choice of either waiting a long time to complete application
shutdown, or shutting down before the client processes are done with the
references.

Thanks for the explanation.
This was approximately what I was doing, and I was worried about this.
I'm returning results from queries to a Postgresql database, and PGresult
objects cannot be marshalled (I'm not sure why).
In practice all clients fetch the results immediately, so it seemed to work
fine, but I want something safer. Maybe creating a dumpable PGresult is the
easiest way to go, but TimerIdConv with a short timeout would also work.
I wonder what happens if a client references a CG removed object: it this
is well-defined I could also re-issue the query in a rescue. The chance
of this happening is quite small after all.

Cheers,

Han Holl
 
E

Eric Hodel

--a8Wt8u1KmwUX3Y2C
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
[ cut ]
This is an example of what not to do:
=20
class RemoteObj
include DRbUndumped
...
end
=20
class Server
def get resource
return RemoteObj.new
end
end
=20
DRb.start service nil, Server.new
=20
You could extend DRb::TimerIdConv to delay shutting down the DRb server
until after all remote objects expire. Unfortunately, this brings you
to the choice of either waiting a long time to complete application
shutdown, or shutting down before the client processes are done with the
references.
=20
In practice all clients fetch the results immediately, so it seemed to wo= rk
fine, but I want something safer. Maybe creating a dumpable PGresult is t= he
easiest way to go, but TimerIdConv with a short timeout would also work.
I wonder what happens if a client references a CG removed object: it this
is well-defined I could also re-issue the query in a rescue. The chance
of this happening is quite small after all.

ObjectSpace._id2ref will raise a RangeError if you attempt to access a
recycled object:

RangeError: 0x4094880 is recycled object

I forget what you get back via DRb when your remote reference has
expired, though. (You should be able to use the example above to find
out.)

--=20
Eric Hodel - (e-mail address removed) - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04


--a8Wt8u1KmwUX3Y2C
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (FreeBSD)

iD8DBQFA1zKAMypVHHlsnwQRAq46AKCcLsa1M0GBsEuL/2ytVCIZsKUWtwCg70vb
CwMt9hpCDG4xCJnsHTCiQvg=
=EVRr
-----END PGP SIGNATURE-----

--a8Wt8u1KmwUX3Y2C--
 
H

Han Holl

Eric Hodel said:
I forget what you get back via DRb when your remote reference has
expired, though. (You should be able to use the example above to find
out.)

You get back a NoMethodError, no such method for nil (NilClass).
(I decided I only ever need #result and #fields, so I return those, no need
for a reference to a server side object).

Thanks for your help.

Cheers,

Han Holl
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,147
Messages
2,570,833
Members
47,380
Latest member
AlinaBlevi

Latest Threads

Top