On Wed, 29 Nov 2006, Daniel Berger wrote: > Tim Pease wrote: > > <snip> > >>> I don't know much about slave, but one question I have right off the >>> bat is why you would want one drb server per object, instead of just >>> one drb server that stored objects in a hash table that you could push >>> and pop at will. Maybe I need to go back and see Ara's use case for >>> this... >>> >> >> Slave forks off a ruby object in a separate process and then uses DRb >> for communication between the processes. Each forked process has its >> own DRb server. >> >> TwP > > Yes, but why? I assume the purpose is IPC. If so, again I ask why you > would need 1 drb server per object instead of one drb server with lots > of objects. If its purspose isn't IPC, what is it? the purpose is two-fold: 1) easy ipc 2) scalling expensive operations across multiple processors easily you certainly could setup a hashtable of objects. but a few things to consider 1) drop-in scalibility object = ExpensiveCalcuation.new # 1000 lines of code change to object = Slave.new{ ExpensiveCalcuation.new } # exact same 1000 lines of code and, whammo. you scale to multi-processor machines. 2) DRbUndumped nuances let's say you build a table of objects like this: harp:~ > cat a.rb require "slave" require "yaml" slave = Slave.new{ Hash.new } table = slave.object array = [] table["array"] = array table["array"] << Process.pid y "slave.pid" => slave.pid y "array" => array y "table['array']" => table["array"] what will happen? harp:~ > ruby a.rb slave.pid: 5258 array: [] table['array']: [] yikes!!! what went wrong? well, consider: array = [] # array is in parent table["array"] = array # array is marshaled across to child as a copy table["array"] << Process.pid # array is marshaled back across to parent and this __local_copy__ is appended too p "array" => array # local copy empty p "table['hash']" => table["hash"] # remote copy empty here is a fix array = [] array.extend DRbUndumped # the important part now, running again harp:~ > ruby a.rb slave.pid: 5302 array: - 5301 table['array']: - 5301 but look carefully this example is even __more__ fubar: the array lives in the parent! we setup a table and sent only the proxy (DRbUndumped) across to the child! we've completely negated the entire benefit of running objects in another process - all we have is a lookup table for objects in our own address space. ok. take two. this time we'll try this: harp:~ > cat a.rb require "slave" require "yaml" slave = Slave.new{ # build table in child table = Hash.new array = [] table["array"] = array table } table = slave.object table["array"] << Process.pid y "slave.pid" => slave.pid y "table['array']" => table["array"] we give a whirl: harp:~ > ruby a.rb slave.pid: 5358 table['array']: [] sigh. now our table exists only in the child, and so does all it's elements. why doesn't it work. DRbUndumped is screwing us again. here's why: table["array"] << Process.pid # here the child marshals a copy back to # parent. we append to the copy y "table['array']" => table["array"] # and here we get a fresh __empty__ copy dang. we know the fix though, in the child we do: array.extend DRbUndumped trying again harp:~ > ruby a.rb slave.pid: 5405 table['array']: !ruby/object:DRb::DRbObject ref: -609755446 uri: drbunix:///tmp/hash_-609755436_5404_5405_0 wtf? well, since our object now lives in the child and we only get a drb proxy back some things work, like '<<', but other methods, like 'to_yaml', and 'inspect' are handled locally by drb. to get around this 'to_yaml' bug we have to force a copy harp:~ > cat a.rb require "slave" require "yaml" slave = Slave.new{ # build table in child table = Hash.new array = [] array.extend DRbUndumped table["array"] = array table } table = slave.object table["array"] << Process.pid y "slave.pid" => slave.pid y "table['array']" => table["array"].map # force local copy, neither dup nor clone will cut it! harp:~ > ruby a.rb slave.pid: 5465 table['array']: - 5464 ah, finally. so, you see, managing a hierarchy of object across drb is tricky. not that it can't be done - i just happen to think that managing __one__ object and it's DRbUndumped nuances is about all most hackers can manage - thus that's the default usage. nothing will stop you from making your server object a factory or table though - it just gets confusing fast. kind regards. -a -- if you want others to be happy, practice compassion. if you want to be happy, practice compassion. -- the dalai lama