hi han-
The problem with this approach is that you have to know the uri of the
server at fork time, which can be a problem.
it shouldn't be, you can do, for example
uri = drbobject.__drburi
eg. if you have a drb object you always have it's uri. if you have it's uri
you can always detach and re-attach. though i agree it's not that elegant.
(And I didn't realize that you can destroy a DRbObject with
DRb.stop_service -- I associate that with the server side of things).
yeah, it seems like it. remember though, every ruby program which uses drb is
a servant - drb is always both server and client. fyi.
I've found a mote generic way of forking a process that is a DRb client, but
this has as drawback that it has an initimate knowlegde of the way DRb is
implemented.
module DRb
class DRbConn
def self.fork
f = @mutex.synchronize do
Process::fork
end
if f.nil?
@pool = []
if block_given?
yield
exit 0
end
end
f
end
end
This just deletes the commection pool in the child. Forking within the
mutex is because it's possible to fork with some other thread having the
mutex locked, which causes problems for the one-thread child.
doesn't it leave open file handles lying around?
But it's a bit of a kludge and I would prefer it if DRbObject had a method
to deal with it.
agreed. it's always tough to carry open file handles across a fork -
sometimes is just seems easier to code around it. for instance, by setting up
a ring server where each service registers in the parent. then all children
simply grab drbobjects of of that ring server. maybe something like this
might apply to your problem:
harp:~ > ruby a.rb
[[:key, :val]]
[:val]
harp:~ > cat a.rb
require 'drb'
require 'rinda/ring'
require 'rinda/tuplespace'
require 'tmpdir'
require 'yaml'
STDOUT.sync = STDERR.sync = true
def start_ring_server
Rinda::RingServer.new Rinda::TupleSpace.new
end
def find_ring_server
Rinda::TupleSpaceProxy.new Rinda::RingFinger::new.lookup_ring_any
end
def drb_join
begin; DRb.thread.join; rescue Exception; exit; end
end
children = []
···
On Sat, 24 Jun 2006, Han Holl wrote:
#
# one process starts a ring server. this could also be the parent. other
# processes, or even the parent, can register drb objects with this ring
# server.
#
children <<
fork{
DRb.start_service
rs = start_ring_server
drb_join
}
#
# this one starts up a hash server and registers it's location
#
children <<
fork{
(dhash = {}).extend DRbUndumped
DRb.start_service nil, dhash
rs = find_ring_server
rs.write [:dhash, dhash]
drb_join
}
#
# this one starts up an array server and registers it's location
#
children <<
fork{
(darray = []).extend DRbUndumped
DRb.start_service nil, darray
rs = find_ring_server
rs.write [:darray, darray]
drb_join
}
#
# now any child, or the parent, can find and use these drb objects without
# knowing their locations or requiring a connection before forking - only
# the 'name' of the object need be known.
#
Process.waitpid fork{
DRb.start_service
rs = find_ring_server
tuple = rs.read [:dhash, nil]
dhash = tuple.last
dhash[:key] = :val
tuple = rs.read [:darray, nil]
darray = tuple.last
darray << :val
}
#
# here the parent finds the dhash and darray to print them out
#
DRb.start_service
rs = find_ring_server
tuple = rs.read [:dhash, nil]
dhash = tuple.last
tuple = rs.read [:darray, nil]
darray = tuple.last
p dhash.map #=> [[:key, :val]]
p darray.map #=> [:val]
#
# wait for children
#
at_exit{
children.each{|cid| Process.kill 'TERM', cid rescue next}
loop{ Process.wait Process::WNOHANG rescue break }
}
STDIN.gets
regards.
-a
--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama