必要にかられて druby の実装を読んでいた。
ブロックの処理がうまくいかないような気がしていて、試してみたら案の定うまく動かなかった。
# server.rb require "drb" class Front def f(&b) @b = b end def g @b.call end end uri = "druby://localhost:55331" DRb.start_service(uri, Front.new) DRb.thread.join
# client.rb require "drb" DRb.start_service front = DRbObject.new_with_uri("druby://localhost:55331") front.f do p 42 end GC.start GC.start GC.start front.g
front.g
を呼ぶときには、front.f
に渡したブロックはGCに回収されてしまっている。
これを回避するにはProc
に対するDRbObject
が死ぬまでProc
を GC に回収されないようにしなければいけないのだけれど、大変そう。というか、これをどうしているかを知りたくて druby のコードを読んでいたのだけど、対応していないので自分で方法を考えなければならない……。druby でやるなら、Proc
はクライアント側でHashにでも詰めておいて、サーバー側のProc
に対するDRbObject
が回収されるときにfinalizerでクライアント側でも回収させるとかかな。だるそう
とここまで書いて、Procじゃなくて普通のオブジェクトでも同じことが起こるのではと思って試したのだけど、こっちは動く。なんでだろう。
# server.rb require "drb" class Front def f(x) @x = x end def g @x.hello end end uri = "druby://localhost:55331" DRb.start_service(uri, Front.new) DRb.thread.join
# client.rb require "drb" DRb.start_service front = DRbObject.new_with_uri("druby://localhost:55331") class C include DRb::DRbUndumped def hello puts 'hello' end end front.f(C.new) GC.start GC.start GC.start front.g