Do i have to use DRbUndumped?

i am currently using Ruby 1.8.4 and DRb 2.0.4, and i am stuck with some
marshalling problem
related to tuplespace. this is my hello world code using tuplespace


#HelloWorld.rb
require “rinda/ring”

class HelloWorld

include DRbUndumped

def initialize(str)
	@str = str
end
def _dump(dumpDepth)
	@str
end
def HelloWorld._load(srcString)
	HelloWorld.new(srcString)
end
def to_s
	@str
end

end

DRb.start_service

ringServer = Rinda::RingFinger.primary
tupleSpace = ringServer.read([:name, :TupleSpace, nil, nil])[2]
tupleSpace = Rinda::TupleSpaceProxy.new tupleSpace

tupleSpace.write([“helloWorldObject”, HelloWorld.new(“Hello World!”)])

aHelloWorldObject = tupleSpace.take([“helloWorldObject”, nil])
puts aHelloWorldObject[1]

#DRb.thread.join


my problem is that _dump doesn’t work, because the HelloWorld object
gets converted into
DRb::DRbUnknown, which can not be converted into tuple to be inserted
into the tuplespace. it does
not occur if i use DRb::DRbUndumped, but i think using DRb::DRbUndumped
is rather unsecure if i
try using read instead of take to get the object out of the tuplespace.
the question is:

  • what’s wrong with my _dump (and _load) ? do i have to use
    DRb::DRbUndumped ?
  • do i have to use Rinda::Ring to work with Rinda::TupleSpace ?

yn Tue, 11 Apr 2006, holy sinner wrote:

  • what’s wrong with my _dump (and _load) ? do i have to use DRb::DRbUndumped ?

harp:~ > cat a.rb
require ‘rinda/ring’

class HelloWorld
def initialize(str) @str = str end
def _dump(*a, &b) Marshal.dump(@str, *a, &b) end
def HelloWorld._load(*a, &b) new(Marshal.load(*a, &b)) end
def to_s() @str end
end

hello_world = HelloWorld.new ‘hello world’

puts(Marshal.load(Marshal.dump(hello_world)))

harp:~ > ruby a.rb
hello world

-a

On Apr 10, 2006, at 8:23 AM, holy sinner wrote:

def initialize(str)
end
aHelloWorldObject = tupleSpace.take([“helloWorldObject”, nil])
DRb::DRbUndumped is rather unsecure if i try using read instead of
take to get the object out of the tuplespace.

Unsecure? Why?

If you’re worried about losing the object due to the taking process
dying use a TupleSpaceProxy. It ensures that the object won’t get lost.

the question is:

  • what’s wrong with my _dump (and _load) ? do i have to use
    DRb::DRbUndumped ?

You should really use marshal_load and marshal_dump.
DRb::DRbUndumped must be used on objects that don’t have their class
present on all ruby processes in the system.

  • do i have to use Rinda::Ring to work with Rinda::TupleSpace ?

No. Rinda::Ring lets you find DRb services easily. It is zeroconf
for DRb.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

thanx, it indeed can replace DRbUndumped, but with the same consequence:
it is still a pass-by-reference thing, which is rather dangerous to be
used when working with tuplespace’s read operation.

consider this, what if two clients read the same object written by some
server, and one of the client modifies the object (hoping it would only
change his “copy of object”). using DRbUndumped or this alternative
marshalling is a bad method, since the object would still appear changed
on both clients.

what i really need is a pass-by-value marshalling so that the one
written into the space is actually the copy of the real object, and not
the reference to it. can anyone help me? i believe the drawback of
having the client to own physical copy of the object’s class (i.e. the
object’s source code) is not something to be worried about. or is there
any other disadvantage of using pass-by-value compared to using
pass-by-reference, maybe speed / execution time?

i currently combine Rinda::TupleSpace and Rinda::Ring instead of putting
the tuplespace as a DRbServer’s front object, trying to make the whole
thing works like jini

Not quoting past messages is very bad form. Please quote relevant
parts of the message you are replying to.

On Apr 11, 2006, at 12:29 AM, xaea alvein wrote:

thanx, it indeed can replace DRbUndumped, but with the same
consequence:
it is still a pass-by-reference thing, which is rather dangerous to be
used when working with tuplespace’s read operation.

#read is not dangerous. #take can lose the object if the taking node
quits before receiving the object, so you should use a
TupleSpaceProxy whenever you take tuples.

consider this, what if two clients read the same object written by
some
server, and one of the client modifies the object (hoping it would
only
change his “copy of object”). using DRbUndumped or this alternative
marshalling is a bad method, since the object would still appear
changed
on both clients.

That is as intended. It is called Distributed Ruby after all.

It sounds like you really want some kind of access control or locking
mechanism.

what i really need is a pass-by-value marshalling so that the one
written into the space is actually the copy of the real object, and
not
the reference to it. can anyone help me? i believe the drawback of
having the client to own physical copy of the object’s class (i.e. the
object’s source code) is not something to be worried about. or is
there
any other disadvantage of using pass-by-value compared to using
pass-by-reference, maybe speed / execution time?

Your problem seems to be an implementation detail. It seems you want
an object usable by only one node at a time.

You should either use take to remove the object from the TupleSpace
or provide locking via the TupleSpace to prevent other nodes from
fiddling with your object while one node is working on it.

Pass by reference allows a transparent object space. Pass by value
is going to complicate your design much more than building atop of
the primitive operations TupleSpace provides.

i currently combine Rinda::TupleSpace and Rinda::Ring instead of
putting
the tuplespace as a DRbServer’s front object, trying to make the whole
thing works like jini

I don’t understand what this means.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Eric H. wrote:

Not quoting past messages is very bad form. Please quote relevant
parts of the message you are replying to.

i am very sorry

i guess i better give an example:

a master/server M has an object A that he want to put into tuplespace
(using write).
a worker/client C1 wants to have a copy of the object A for himself to
work with (by using read, instead of take).
a worker/client C2 also wants copy of object A (also using read).

the problem is, i currently only know that M have to use
DRb::DRbUndumped (or use the alternative dumping as listed in the first
reply of this topic by -a) if A is to be put into tuplespace, which is a
pass-by-reference, meaning that the copy of A that each client C1 and C2
has is actually the very same object currently residing in master M
(since the one put into the tuplespace is none other than DRbObject
reference to the object A)

what i need is that M to put exactly a copy of object A into the
tuplespace instead just a reference to the object A, and C1 and C2 to
each have the copy of the copy of object A that was previously inserted
into the tuplespace, so that if C1 or C2 each modifies the copy (of copy
of A, if that matters), it only appears to himself. this is what i
believe is a pass-by-value

#read is not dangerous. #take can lose the object if the taking node
quits before receiving the object, so you should use a
TupleSpaceProxy whenever you take tuples.

i am using tuplespaceproxy, thank you

That is as intended. It is called Distributed Ruby after all.

It sounds like you really want some kind of access control or locking
mechanism.

Your problem seems to be an implementation detail. It seems you want
an object usable by only one node at a time.

You should either use take to remove the object from the TupleSpace
or provide locking via the TupleSpace to prevent other nodes from
fiddling with your object while one node is working on it.

Pass by reference allows a transparent object space. Pass by value
is going to complicate your design much more than building atop of
the primitive operations TupleSpace provides.

i currently combine Rinda::TupleSpace and Rinda::Ring instead of
putting
the tuplespace as a DRbServer’s front object, trying to make the whole
thing works like jini

I don’t understand what this means.

javaspace is a service to jini. for further reference, please use
http://www.jini.org

i am using Rinda::TupleSpace and Rinda::Ring based on your example, Mr.
Eric, and i prefer using it compared to serving a TupleSpace instance as
a DRbServer’s front object, since the Ring API works somehow like jini’s
lookup service

maybe some code could illustrate better:

[assuming there is a TupleSpace-based name server and TupleSpace
provider, like the one given in Mr. Eric H.'s Ring example in his
Segment7 site]


#HelloWorld.rb

class HelloWorld
attr_writer :str

you can use DRbUndumped or the following.

either results in the same

def initialize(str)
	@str = str
end
def _dump(*args, &block)
	Marshall.dump(@str, *args, &block)
end
def HelloWorld._load(*args, &block)
	HelloWorld.new(Marshall.load(*args, &block))
end
def to_s
	@str
end

end


#Master.rb

require “rinda/ring”
require “HelloWorld”

DRb.start_service

ringServer = Rinda::RingFinger.primary
tupleSpace = ringServer.read([:name, :TupleSpace, nil, nil])[2]
tupleSpace = Rinda::TupleSpaceProxy.new tupleSpace

tupleSpace.write([“helloWorldObject”, HelloWorld.new(“Hello World!”)])

DRb.thread.join


#Client1.rb

require “rinda/ring”
#require “HelloWorld”

DRb.start_service

ringServer = Rinda::RingFinger.primary
tupleSpace = ringServer.read([:name, :TupleSpace, nil, nil])[2]
tupleSpace = Rinda::TupleSpaceProxy.new tupleSpace

loop {
aHelloWorldObject = tupleSpace.read([“helloWorldObject”, nil])
puts aHelloWorldObject[1]
}


#Client2.rb

require “rinda/ring”
#require “HelloWorld”

DRb.start_service

ringServer = Rinda::RingFinger.primary
tupleSpace = ringServer.read([:name, :TupleSpace, nil, nil])[2]
tupleSpace = Rinda::TupleSpaceProxy.new tupleSpace

aHelloWorldObject = tupleSpace.read([“helloWorldObject”, nil])
aHelloWorldObject[1].str = “Goodbye!”


anyone can help me with HelloWorld’s dumping alternative, or do i have o
use DRbUndumped / pass-by-reference? i am expecting that each client
gets a fresh copy of HelloWorld object, not a reference to it

xaea alvein wrote:

i guess i better give an example:

a master/server M has an object A that he want to put into tuplespace
(using write).
a worker/client C1 wants to have a copy of the object A for himself to
work with (by using read, instead of take).
a worker/client C2 also wants copy of object A (also using read).

the problem is, i currently only know that M have to use
DRb::DRbUndumped (or use the alternative dumping as listed in the first
reply of this topic by -a) if A is to be put into tuplespace, which is a
pass-by-reference, meaning that the copy of A that each client C1 and C2
has is actually the very same object currently residing in master M
(since the one put into the tuplespace is none other than DRbObject
reference to the object A)

what i need is that M to put exactly a copy of object A into the
tuplespace instead just a reference to the object A, and C1 and C2 to
each have the copy of the copy of object A that was previously inserted
into the tuplespace, so that if C1 or C2 each modifies the copy (of copy
of A, if that matters), it only appears to himself. this is what i
believe is a pass-by-value