Removing methods from DRbObject

T

Tim Bates

My application is using DRb extensively in support of its client-server
model. Ideally I would like to have the remote objects in the client
scripts appear exactly as they would if they were local. All my data
objects include DRb::DRbUndumped so that only references are passed
across the network, as the objects' code needs to run on the server
(database access etc). Unfortunately, DRb::DRbObject defines a bunch of
methods which it doesn't really use, such as ==, ===, <=> etc; but
because it defines them, calls to them don't get proxied to the server.

The Criteria module has in it a neat little bit of code that looks like
this:

mask = ["__send__", "__id__", "inspect", "class", "is_a?", "dup",
"instance_eval"];
methods = instance_methods(true)
methods = methods - mask

methods.each do |m|
undef_method(m)
end

This removes all methods from the class except those in mask.
Something like this in DRb::DRBObject, with an appropriate mask list,
would be really useful, because at the moment, if I have two DRbObjects
which represent the same object on the remote side, the == method still
returns false because of the way DRbObject defines == (the default way,
if it's not exactly the same object they're not equal).

Therefore I have three questions:
1) Is this a reasonable change to make?
2) What is an appropriate mask list to use for DRb::DRbObject?
3) Can I get this change into the core library?
 
R

Robert Klemme

Tim Bates said:
My application is using DRb extensively in support of its client-server
model. Ideally I would like to have the remote objects in the client
scripts appear exactly as they would if they were local. All my data
objects include DRb::DRbUndumped so that only references are passed
across the network, as the objects' code needs to run on the server
(database access etc). Unfortunately, DRb::DRbObject defines a bunch of
methods which it doesn't really use, such as ==, ===, <=> etc; but
because it defines them, calls to them don't get proxied to the server.

The Criteria module has in it a neat little bit of code that looks like
this:

mask = ["__send__", "__id__", "inspect", "class", "is_a?", "dup",
"instance_eval"];
methods = instance_methods(true)
methods = methods - mask

methods.each do |m|
undef_method(m)
end

This removes all methods from the class except those in mask.
Something like this in DRb::DRBObject, with an appropriate mask list,
would be really useful, because at the moment, if I have two DRbObjects
which represent the same object on the remote side, the == method still
returns false because of the way DRbObject defines == (the default way,
if it's not exactly the same object they're not equal).

Therefore I have three questions:
1) Is this a reasonable change to make?
2) What is an appropriate mask list to use for DRb::DRbObject?
3) Can I get this change into the core library?

I'll prefer to raise another issue: usually it is not a good idea to
reference masses of instances remotely. Thies yields hight network load
since lot's of methods are not invoked locally but remotely. This can
degenerate to a degree where an application is no longer usable. Did you
verify that your application does not suffer from this performance
degeneration? If not, I'd first verify that usig lots of instances
remotely is practical. While transparent distribution of instances sounds
like a good thing, a typical application using distribution should / must
be aware of the distribution in order to do things efficiently. In your
case it *might* be better to transfer an array or hash of data objects to
the client, work with then and send them back afterwards.

Just my 0.02EUR...

Kind regards

robert
 
J

Joel VanderWerf

Tim said:
This removes all methods from the class except those in mask.
Something like this in DRb::DRBObject, with an appropriate mask list,
would be really useful, because at the moment, if I have two DRbObjects
which represent the same object on the remote side, the == method still
returns false because of the way DRbObject defines == (the default way,
if it's not exactly the same object they're not equal).

You might want consider requiring drb/eq, which defines #== and #hash in
terms of the remote reference, rather than object identity.
 
T

Tim Bates

Joel said:
You might want consider requiring drb/eq, which defines #== and #hash in
terms of the remote reference, rather than object identity.

class DRbObject
def ==(other)
return false unless DRbObject === other
(@ref == other.__drbref) && (@uri == other.__drburi)
end

This doesn't do what I want either. It does some comparison of whether
they represent *the same object* on the remote side. In my case, they
don't - but the remote objects have a definition of #== that makes them
equal. This doesn't solve my problem.

By undefining #==, #inspect, #class and so on, you could make a
DRbObject appear and behave exactly like the local one. I'm not sure how
many of these such methods it is wise to undefine, though - some may be
crucial to the way DRb works. Can someone with a knowledge of the
internals of DRb please tell me if I'll get into trouble by undefining
the wrong methods, and what those methods are?
 

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

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top