Forum: Ruby do i have to use DRbUndumped?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
holy sinner (Guest)
on 2006-04-10 19:26
(Received via mailing list)
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 ?
unknown (Guest)
on 2006-04-10 19:44
(Received via mailing list)
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
Eric H. (Guest)
on 2006-04-10 22:12
(Received via mailing list)
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. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
Xaea A. (Guest)
on 2006-04-11 11:29
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
Eric H. (Guest)
on 2006-04-11 21:50
(Received via mailing list)
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. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
xaea alvein (Guest)
on 2006-04-12 11:48
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
xaea alvein (Guest)
on 2006-04-13 21:20
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
>
This topic is locked and can not be replied to.