分散GCのかなりいいかげんな実装の提案*1。
定期的に自分が知っているDRbObjectにメソッド(respond_to?)を投げる係を置くですよ。
require 'drb/drb' require 'thread' class DRbPing def initialize(timeout=300) @timeout = timeout @queue = Queue.new @keeper = keeper @knocker = knocker end def keeper Thread.new do loop do en_q sleep(@timeout) end end end def knocker Thread.new do loop do begin @queue.pop.respond_to? :to_a rescue end end end end def en_q ObjectSpace.each_object(DRb::DRbObject) do |ro| @queue.push(ro) end end end
DRbPing.newして使います。
require 'drb_ping' ping = DRbPing.new DRb.start_service ....
このpingされる相手は、最後のアクセスから一定時間GCから保護するDRbIdConvの代替品、TimerIdConvをインストールしたサービスです。
TiemerIdConvがインストールされたサービスでは、外部に送り出したDRbObjectの本物の方のオブジェクトを保持するので、一時的なオブジェクトであれ、アクセスから一定時間は削除されません。
require 'drb/timeridconv' .... DRb.install_id_conv(DRb::TimerIdConv.new) DRb.start_service(nil, Foo.new)
*1:だれに提案してるかはまだ秘密