From: Brian Candler Date: 2003-03-07T08:44:16+09:00 Subject: DRB and threads I wonder if anyone can give me some hints on the interactions between dRuby (drb) and threads. I have been having a bit of a play, and it seems if you set up a dRuby server in the way described in the Pickaxe, then each incoming request is handled as a separate thread, but method calls are made to the *same* object concurrently. Example: # server.rb require 'drb' class SlowServer def doit(x) puts "Starting #{x}..." sleep 3 puts "Finished #{x}" nil end end a = SlowServer.new DRb.start_service('druby://localhost:9000', a) DRb.thread.join # client.rb require 'drb' DRb.start_service # not sure what this does for a client? obj = DRbObject.new(nil, 'druby://localhost:9000') 10.times { obj.doit($$) } Now, if I run two copies of client.rb concurrently as two separate processes, they both only take 30 seconds to complete. The 'doit' method is being run twice on the same object instance. If I understand this rightly, then I can't see how you can use this with any object which carries state unless you rewrite or wrap all the methods to make them thread-safe. Is this correct? Unfortunately I can't find much documentation in English, and I can't see if there's another way of running it - even simple serialisation, so that method calls are handled one at a time. Anyway, the pattern I really want to implement is a pool of objects, with the method call handed to any free object (and that object does not get another request until it has finished handling the first one). The aplication is that I have a database front-end class where each instance keeps a DBI handle open (amongst other things) but each method call is independent of the previous one, i.e. there's no state kept *between* calls, other than inside the database itself of course. So incoming requests can be farmed off to any object which is free. Do I have to write a wrapper object which duplicates every method in my database class (or method_missing)? Or is there a simpler way of handling this? Another solution would be if I could run a DRb server under FastCGI, so that I had a pool of processes (maintained by Apache) and requests would be farmed out to those processes. Is that possible? Thanks, Brian. [P.S. I am using dRuby-2.0.2 with ruby-1.6.8]