On Wed, 28 Mar 2001 22:23:00 +0900, chad fowler wrote:

>> I made a simple script to test distributed objects:
>Would you be able to post the source for download somewhere?

Well, I made two small sample programs, a server and a client.
They look bad because I'm a newbie. :)

It looks like there are two separate problems:

* test1 and test2 do many method calls, and each call consumes one socket
which is left in TIME_WAIT state for some time. After a number of
transaction, the kernel runs out of buffers and bad things happen (locks,
or ENOBUFS error messages).

Is it possible to tell DRb to use a single socket connection? 
Could it use UDP as an option?

* test3 calls a remote object, which has been created by another remote
object. test3 sometimes (rarely) gives the "recycled object" error message
on the client side.

Files follow:

=== server.rb ===

require 'thread'
require 'drb/drb'

class ServerChild
  include DRbUndumped
  def simple_method
    puts "A simple child method"
  end
  def callback_method (object)
    puts "I call back object #{object.id} from " + 
      "child and get: '#{object.callback}'"
  end
end

# A simple server object

class ServerObject
  include DRbUndumped
  def simple_method
    puts "A simple method"
  end
  def callback_method (object)
    # try to call back an object on the remote (client) side
    puts "I call back object #{object.id} and get: '#{object.callback}'"
  end
  def createChild
    ServerChild.new
  end
end

# just run the server and wait

if __FILE__ == $0
  here = ARGV.shift
  x = ServerObject.new
  DRb.start_service(here, x)
  puts "Server URI is #{DRb.uri}"
  DRb.thread.join
end


=== client.rb ===

require 'drb/drb'

# a simple class with a method that will be called from the remote server

class CallbackTarget
  include DRbUndumped
  def callback
    puts "Somebody called me from remote server"
    "a result"
  end
end

# Call a remote server method 10000 times. It works, but locks because the
# operating system runs out of buffers: too many sockets are left in
# TIME_WAIT state.

def test1 (remote)
  10000.times do |x|
    puts "Iteration #{x}"
    remote.simple_method
  end
end

# Call a remote server method 10000 times. Same as test1, but should hang
# after half of test1's connections: each transaction consumes 2 sockets
# (invocation and callback)

def test2 (remote)
  c = CallbackTarget.new
  10000.times do |x|
    puts "Iteration #{x}"
    remote.callback_method c
  end
end

# Create an object on the remote server and call its method many times. I
# don't know if I am supposed to be able to do this, but it gives the
# "recycled object" message on client side.

def test3 (remote)
  child = remote.createChild
  c = CallbackTarget.new
  10000.times do |x|
    puts "Iteration #{x}"
    child.callback_method c
  end
end

if __FILE__ == $0
  there = ARGV.shift
  DRb.start_service ()
  r = DRbObject.new (nil, there)
  # choose a test here :)
  test3 r
end

-- 
disclaimer: not speaking for anybody but me.