DRB class in array

M

Master Marv

hi,
i would like to store an array of this very simple class on a drb server

class IEB_wrapper1
attr_accessor :status

def initialize
@status="ready"
end
end

the object on the drb server is an array:
dump=[]
DRb.start_service "druby://BLA:55555", dump


if a client modifies the status variable of a class instance in the
array it does not get changed.

dump = DRbObject.new nil, ARGV.shift
myclass = IEB_wrapper1.new
dump.push myclass
dump[0].status = "Hello"
p dump[0].status => results in "ready" not in "Hello"

how can i modify the status of my class in the array on the drb server?
 
B

Brian Candler

Master said:
if a client modifies the status variable of a class instance in the
array it does not get changed.

dump = DRbObject.new nil, ARGV.shift
myclass = IEB_wrapper1.new
dump.push myclass
dump[0].status = "Hello"
p dump[0].status => results in "ready" not in "Hello"

how can i modify the status of my class in the array on the drb server?

class IEB_wrapper1
include DRbUndumped
end

This means that instead of passing across a *copy* of the object (made
using Marshal.dump and load), it will pass across a DRb *proxy object*.
All operations made on that proxy are sent across as remote method calls
and therefore made on the server.

I wrote a document called "DrbTutorial" on rubygarden.org, which
unfortunately is long since gone. You might be able to find a cached
copy somewhere.
 
M

Master Marv

include DRbUndumped
this seems to let the class reside wherever it has been generated.
is it possible to generate a class on a drb client, copy it to the
server and then let it stay there (ie. further interaction with the
class should be made with the the class on the server and not with local
copies).

what i want to do is the following:
i have a class that has a run and a status function. when the run
function is invoked the class computes something for ~5minutes.
the calculation should happen on the drb server.
multiple drb clients should generate classes on the server(or locally
and copy them to the server), so that the server does the computation.
after the jobs have been started (remote_job_array[x].start) the clients
terminate. other clients that should check the status of the computation
via a status function (remote_job_array[x].status) of the class on the
server.
 
B

Brian Candler

Master said:
this seems to let the class reside wherever it has been generated.
is it possible to generate a class on a drb client, copy it to the
server and then let it stay there (ie. further interaction with the
class should be made with the the class on the server and not with local
copies).

DRb has no real concept of a "server" or a "client" - connections can be
opened and method calls made from either side.

You could originate your object, pass it across to another place, and at
that point do
obj.extend DRbUndumped
which will lock it there.

But perhaps more sensible is to pass across the *parameters* needed to
make the object, i.e. have a class method on the server such as

def Foo.make_status(*args)
IEB_wrapper1.new(*args)
end

and you share the Foo object via DRb.
 
R

Robert Klemme

2009/11/26 Master Marv said:
=A0 include DRbUndumped
this seems to let the class reside wherever it has been generated.
is it possible to generate a class on a drb client, copy it to the
server and then let it stay there (ie. further interaction with the
class should be made with the the class on the server and not with local
copies).

what i want to do is the following:
i have a class that has a run and a status function. when the run
function is invoked the class computes something for ~5minutes.
the calculation should happen on the drb server.
multiple drb clients should generate classes on the server(or locally
and copy them to the server), so that the server does the computation.
after the jobs have been started (remote_job_array[x].start) the clients
terminate. other clients that should check the status of the computation
via a status function (remote_job_array[x].status) of the class on the
server.

DRb does not implement the concept of moving *code* around. You
either have to do it manually (there are several ways to do that) or
you have to require the class needed for the operation to be present
on the server already.

Ways how you can send over code:

- as a string of valid Ruby code (very insecure)
- as the name of a file to load on the server (a bit more secure)
- as a string of a particular DSL you invent for the task
- in your case you might be able to parametrize class generation and
do it completely on the server

Kind regards

robert

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

Sausheong Chang

Hi

I have a slightly different problem. I have an array stored in the
object:

class Room
include DRb::DRbUndumped
attr_accessor :name
attr_accessor :game
attr_accessor :eek:bservers

def initialize(name=nil)
@game = nil
@observers = []
@name = name
end
end

And the object is stored at the 'server'. At the 'client' I got the
object and is able to modify the @name instance variable at the
'server'. However when I tried to add objects to the @observers array it
doesn't seem to appear at the 'server'. What could be wrong?


Brian said:
Master said:
if a client modifies the status variable of a class instance in the
array it does not get changed.

dump = DRbObject.new nil, ARGV.shift
myclass = IEB_wrapper1.new
dump.push myclass
dump[0].status = "Hello"
p dump[0].status => results in "ready" not in "Hello"

how can i modify the status of my class in the array on the drb server?

class IEB_wrapper1
include DRbUndumped
end

This means that instead of passing across a *copy* of the object (made
using Marshal.dump and load), it will pass across a DRb *proxy object*.
All operations made on that proxy are sent across as remote method calls
and therefore made on the server.

I wrote a document called "DrbTutorial" on rubygarden.org, which
unfortunately is long since gone. You might be able to find a cached
copy somewhere.
 
B

Brian Candler

Sausheong said:
I have a slightly different problem. I have an array stored in the
object:

class Room
include DRb::DRbUndumped
attr_accessor :name
attr_accessor :game
attr_accessor :eek:bservers

def initialize(name=nil)
@game = nil
@observers = []
@name = name
end
end

And the object is stored at the 'server'. At the 'client' I got the
object and is able to modify the @name instance variable at the
'server'. However when I tried to add objects to the @observers array it
doesn't seem to appear at the 'server'. What could be wrong?

Try this:

@observers = [].extend DRb::DRbUndumped

I think the same thing is happening one level down: although the Room
instance stays where it is, when you make a call across the net to
room.observers the return value is a *copy* of this array.

Another solution is to remove the attr_accessor for observers
completely, and instead implement separate methods for what the client
really needs to do - e.g. add an observer, remove an observer, iterate
across observers.
 
S

Sausheong Chang

Thanks! That worked, though a bit messier than I would have liked it.


Brian said:
Try this:

@observers = [].extend DRb::DRbUndumped

I think the same thing is happening one level down: although the Room
instance stays where it is, when you make a call across the net to
room.observers the return value is a *copy* of this array.

Another solution is to remove the attr_accessor for observers
completely, and instead implement separate methods for what the client
really needs to do - e.g. add an observer, remove an observer, iterate
across observers.
 

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,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top