Why can't I return "Threads.list" Array in DRb?

Hi, I can't understand why I can't return the current "Threads.list" array in
a DRb server method.

- In the DRb server object I just do:

  def current_threads
    Thread.list
  end

- And the DRb client calls:

  drb_client.current_threads

but instead of an Array object I get a DRb::DRbObject, and in each call to
this method I get a different "id":

drb_client.current_threads

=> #<DRb::DRbObject:0xb7b8d384 @ref=-608642478, @uri="druby://0.0.0.0:10001">

drb_client.current_threads

=> #<DRb::DRbObject:0xb7b8b675 @ref=-608644410, @uri="druby://0.0.0.0:10001">

Of course, I'm 100% sure that "Thread.list" returns an Array. If I return any
other Array all works ok:

- DRb server:

  def current_threads
    [1,2,3,4,5]
  end

drb_client.current_threads

[1,2,3,4,5]

Why does this issue occur when returning "Thread.list"?

Thanks for any help.

···

--
Iñaki Baz Castillo

- In the DRb server object I just do:

  def current_threads
    Thread.list
  end

- And the DRb client calls:

  drb_client.current_threads

but instead of an Array object I get a DRb::DRbObject, and in each call to
this method I get a different "id":

> drb_client.current_threads
=> #<DRb::DRbObject:0xb7b8d384 @ref=-608642478,
@uri="druby://0.0.0.0:10001">
> drb_client.current_threads
=> #<DRb::DRbObject:0xb7b8b675 @ref=-608644410,
@uri="druby://0.0.0.0:10001">

Opsss, and more extrange:
Note the following:

drb_client.current_threads

=> #<DRb::DRbObject:0xb7b8d384 @ref=-608642478, @uri="druby://0.0.0.0:10001">

puts drb_client.current_threads

#<Thread:0xb7c8f700>
#<Thread:0xb76f9598>
#<Thread:0xb76f9a98>
#<Thread:0xb76f9890>
#<Thread:0xb76f91b0>
=> nil

How is it possible? why "puts" gets this?

puts drb_client.current_threads.class

DRb::DRbObject
=> nil

···

El Domingo, 29 de Junio de 2008, Iñaki Baz Castillo escribió:

--
Iñaki Baz Castillo

Threads are local to a process so it does not make any sense to
transfer them to another process.

What are you trying to achieve?

Cheers

robert

···

2008/6/29 Iñaki Baz Castillo <ibc@aliax.net>:

Hi, I can't understand why I can't return the current "Threads.list" array in
a DRb server method.

- In the DRb server object I just do:

def current_threads
   Thread.list
end

- And the DRb client calls:

drb_client.current_threads

but instead of an Array object I get a DRb::DRbObject, and in each call to
this method I get a different "id":

> drb_client.current_threads
=> #<DRb::DRbObject:0xb7b8d384 @ref=-608642478, @uri="druby://0.0.0.0:10001">
> drb_client.current_threads
=> #<DRb::DRbObject:0xb7b8b675 @ref=-608644410, @uri="druby://0.0.0.0:10001">

Of course, I'm 100% sure that "Thread.list" returns an Array. If I return any
other Array all works ok:

- DRb server:

def current_threads
   [1,2,3,4,5]
end

> drb_client.current_threads
[1,2,3,4,5]

Why does this issue occur when returning "Thread.list"?

--
use.inject do |as, often| as.you_can - without end

Well, I am understanding that if DRb server return an object unknown for the
DRb client, the the only way the client hast to use/show it is as raw value,
is it?

···

El Domingo, 29 de Junio de 2008, Iñaki Baz Castillo escribió:

El Domingo, 29 de Junio de 2008, Iñaki Baz Castillo escribió:
> - In the DRb server object I just do:
>
> def current_threads
> Thread.list
> end
>
> - And the DRb client calls:
>
> drb_client.current_threads
>
> but instead of an Array object I get a DRb::DRbObject, and in each call
> to this method I get a different "id":
>
> > drb_client.current_threads
> => #<DRb::DRbObject:0xb7b8d384 @ref=-608642478,
> @uri="druby://0.0.0.0:10001">
> > drb_client.current_threads
> => #<DRb::DRbObject:0xb7b8b675 @ref=-608644410,
> @uri="druby://0.0.0.0:10001">

Opsss, and more extrange:
Note the following:

> drb_client.current_threads
=> #<DRb::DRbObject:0xb7b8d384 @ref=-608642478,
@uri="druby://0.0.0.0:10001">

> puts drb_client.current_threads
#<Thread:0xb7c8f700>
#<Thread:0xb76f9598>
#<Thread:0xb76f9a98>
#<Thread:0xb76f9890>
#<Thread:0xb76f91b0>
=> nil

How is it possible? why "puts" gets this?

> puts drb_client.current_threads.class
DRb::DRbObject
=> nil

--
Iñaki Baz Castillo

My projects binds for TCP connections (threads) and I want to monitorize them,
so I get them via DRb.

Anyway I've changed the data transferred: instead of "Thread.list" (that is
not serializable) I do something as:
  Thread.list.map {|t| {"id"=>t.id, "status"=>t.status ...... }

I have enough with that :slight_smile:

···

El Lunes, 30 de Junio de 2008, Robert Klemme escribió:

Threads are local to a process so it does not make any sense to
transfer them to another process.

What are you trying to achieve?

--
Iñaki Baz Castillo

It seems more like a situation where DRb detects that the return
object (the Array) is not fully serializable (contains non-
derializable objects), and hence it returns a "server reference" or
"proxy object" for the object instead. Whenever you invoke method on
the proxy object, they are invoked on the server.

This is really the beauty of DRb: Objects that can't be marshalled /
serialized, become remote objects automatically. You can even 'yield'
to blocks on the client, which is what happens when you "puts" the
array.

Here's a simpler example:

class Thing
  include DRb::DRbUndumped # make sure instance are not marshalled and
transferred
  def each
    puts "each called on server"
    3.times { |i| yield(i) }
  end
end
class Server
  def create_thing
    Thing.new
  end
end
DRb::start_service("druby://:12000", Server.new)
DRb.thread.join

And a client:

DRb.start_service
remoteServer = DRb::DRbObject.new(nil, "druby://localhost:12000")
remoteThing = remoteServer.create_thing
remoteThing.each { |i| p i }

The 'remoteThing' becomes a DRb::DRbObject which serves as a proxy to
the Thing object on the server. Thing#each is actally run on the
server and yields back to the block on the client.

Lars

···

On Jun 29, 7:00 pm, Iñaki Baz Castillo <i...@aliax.net> wrote:

El Domingo, 29 de Junio de 2008, Iñaki Baz Castillo escribió:
> El Domingo, 29 de Junio de 2008, Iñaki Baz Castillo escribió:
> > but instead of an Array object I get a DRb::DRbObject, and in each call
> > to this method I get a different "id":

Well, I am understanding that if DRb server return an object unknown for the
DRb client, the the only way the client hast to use/show it is as raw value,
is it?

Really espectacular :slight_smile:

···

El Lunes, 30 de Junio de 2008, Lars Christensen escribió:

The 'remoteThing' becomes a DRb::DRbObject which serves as a proxy to
the Thing object on the server. Thing#each is actally run on the
server and yields back to the block on the client.

--
Iñaki Baz Castillo