When working locally with an object whose attribute is meant to store
an array, I have no problem making calls like:
object.items << new_item
If I try to do the same thing with a DRb object, though, appending has
no effect on the remote object. I’ve distilled the problem down to
this example…
My server:
require ‘drb’
class TestServer
attr_accessor :items
def initialize
@items = []
end
def add_item(item)
@items << item
end
def add
sum = 0
@items.each {|item| sum += item}
sum
end
end
server = TestServer.new
DRb.start_service(‘druby://localhost:9000’, server)
DRb.thread.join
My client:
require ‘drb’
DRb.start_service()
obj = DRbObject.new(nil, ‘druby://localhost:9000’)
obj.items << 1 #No effect.
obj.items << 2 #No effect.
items = [1, 2]
obj.items = items #Works.
obj.add_item(1) #Works.
obj.add_item(2) #Works.
puts obj.add #Gives ‘6’ instead of ‘9’.
I’d rather my client programs be able to use append (<<) instead of an
add_item(item) method or direct assignment. How can I do this?
Jay McGavren wrote:
When working locally with an object whose attribute is meant to store
an array, I have no problem making calls like:
object.items << new_item
If I try to do the same thing with a DRb object, though, appending has
no effect on the remote object.
The #items method returns an Array. That Array is not DRbUndumped (i.e.,
not a proxy object), so it gets copied back to the client. Modifying
that copy in the client can’t affect the original in the server.
Your #add_item method is a good way around this.
Or, you could extend the array with DRbUndumped, to keep it on the
server.
Jay McGavren wrote:
When working locally with an object whose attribute is meant to store
an array, I have no problem making calls like:
object.items << new_item
If I try to do the same thing with a DRb object, though, appending has
no effect on the remote object. I’ve distilled the problem down to
this example…
The BackgrounDRb mailing list will give you better odds of a good
answer.
In general, I treat my background threads with the strictest isolation,
and
I don’t go passing arrays back and forth. Consider the marshalling that
must
occur just for one stinkin’ <<. So I don’t know the answer to your
question,
even though I have used BackgrounDRb on 2 projects so far…
On 7/29/07, Phlip [email protected] wrote:
The BackgrounDRb mailing list will give you better odds of a good answer.
In general, I treat my background threads with the strictest isolation, and
I don’t go passing arrays back and forth. Consider the marshalling that must
occur just for one stinkin’ <<. So I don’t know the answer to your question,
even though I have used BackgrounDRb on 2 projects so far…
–
Phlip
Note that he is not using BackgroundDRb, but DRb itself, so I believe
this list is the most appropriate.
You should probably just extend the array with DRbUndumped, that will
(IIRC) speed up the appending, and allow << to work properly.
On Jul 30, 8:33 am, “Chris C.” [email protected] wrote:
You should probably just extend the array with DRbUndumped, that will
(IIRC) speed up the appending, and allow << to work properly.
Thusly, yes?
Server:
require ‘drb’
class UndumpedArray < Array
include DRbUndumped
end
class TestServer
attr_accessor :items
def initialize
@items = UndumpedArray.new
end
def add
sum = 0
@items.each {|item| sum += item}
sum
end
end
server = TestServer.new
DRb.start_service(‘druby://localhost:9000’, server)
DRb.thread.join
Client:
require ‘drb’
DRb.start_service()
obj = DRbObject.new(nil, ‘druby://localhost:9000’)
obj.items << 1
obj.items << 2
puts obj.add #Gives ‘3’.
Seems to work pretty well. DRbUndumped may be the solution to my
concerns about network overhead as well.
Thanks to everyone for the assistance!
-Jay
On Jul 30, 2007, at 13:35, Jay McGavren wrote:
include DRbUndumped
end
class TestServer
attr_accessor :items
def initialize
@items = UndumpedArray.new
Get rid of UndumpedArray.
@items = Array.new
@items.extend DRbUndumped