[#45530] [ruby-trunk - Feature #6311][Open] memmem()によるrb_memsearch()の高速化 — "Glass_saga (Masaki Matsushita)" <glass.saga@...>

12 messages 2012/04/17

[#45554] [ruby-trunk - Bug #6344][Open] 1.9.3 p125, p194 ruby causes SEGV with test_massign.rb on ppc/ppc64 — "mtasaka (Mamoru Tasaka)" <mtasaka@...>

14 messages 2012/04/23

[ruby-dev:45547] Re: drb SSL test timeout

From: Tanaka Akira <akr@...>
Date: 2012-04-22 03:31:47 UTC
List: ruby-dev #45547
2012年4月22日6:52 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>:

>> あとこの変更では、プロセスが残るのはそのままです。
>> drb が起動したプロセス (あるいは Process.detach が返したスレッド) を覚えていてくれると
>> kill できるような気がするんですが、どうでしょうか。
>
> すみません。どうしたらいいか考えます。

drb 側で覚えておいてもらわなくても、
Process.detach が生成するスレッドを Thread.list から探せば
対処できるのではないか、と思いついたのでやってみました。

まず、kill するときに、/bin/sh だけを kill してしまわないよう、
spawn に渡すのは配列でコマンドを渡して /bin/sh を経由しないようにします。
このために DRb::ExtServManager.command の形式を拡張して、
ハッシュの値に配列も受け入れることになります。

そして、Process.detach が生成するスレッドのスレッド変数に
サービスの名前を入れておいて、後から識別できるようにします。
現在のテストでは問題ないのですが一般には ExtServManager に複数の
インスタンスがありうるような気もするので、
ここはサービスの名前だけじゃなくて、
ExtServManager のインスタンスも入れておいたほうがいいかもしれません。

あとは、setup で @service_name にサービスの名前を保存しておいて、
teardown で Thread.list から探し出して kill しています。
あと、teardown では DRbService.manager.unregist も呼び出してつじつまを
合わせます。

いかがでしょうか。

% svn diff --diff-cmd diff -x '-u -p'
Index: lib/drb/extservm.rb
===================================================================
--- lib/drb/extservm.rb	(revision 35422)
+++ lib/drb/extservm.rb	(working copy)
@@ -79,7 +79,15 @@ module DRb
         @servers[name] = false
       end
       uri = @uri || DRb.uri
-      Process.detach spawn("#{command} #{uri} #{name}")
+      if command.respond_to? :to_ary
+        command = command.to_ary + [uri, name]
+        pid = spawn(*command)
+      else
+        pid = spawn("#{command} #{uri} #{name}")
+      end
+      th = Process.detach(pid)
+      th[:drb_service] = name
+      th
     end
   end
 end
Index: test/drb/test_drbunix.rb
===================================================================
--- test/drb/test_drbunix.rb	(revision 35422)
+++ test/drb/test_drbunix.rb	(working copy)
@@ -20,7 +20,8 @@ end
 class TestDRbUNIXCore < Test::Unit::TestCase
   include DRbCore
   def setup
-    @ext = DRbUNIXService.ext_service('ut_drb_drbunix.rb')
+    @service_name = 'ut_drb_drbunix.rb'
+    @ext = DRbUNIXService.ext_service(@service_name)
     @there = @ext.front
   end

@@ -37,7 +38,8 @@ end
 class TestDRbUNIXAry < Test::Unit::TestCase
   include DRbAry
   def setup
-    @ext = DRbUNIXService.ext_service('ut_array_drbunix.rb')
+    @service_name = 'ut_array_drbunix.rb'
+    @ext = DRbUNIXService.ext_service(@service_name)
     @there = @ext.front
   end
 end
Index: test/drb/test_drbssl.rb
===================================================================
--- test/drb/test_drbssl.rb	(revision 35422)
+++ test/drb/test_drbssl.rb	(working copy)
@@ -36,7 +36,8 @@ end
 class TestDRbSSLCore < Test::Unit::TestCase
   include DRbCore
   def setup
-    @ext = DRbSSLService.ext_service('ut_drb_drbssl.rb')
+    @service_name = 'ut_drb_drbssl.rb'
+    @ext = DRbSSLService.ext_service(@service_name)
     @there = @ext.front
   end

@@ -53,7 +54,8 @@ end
 class TestDRbSSLAry < Test::Unit::TestCase
   include DRbAry
   def setup
-    @ext = DRbSSLService.ext_service('ut_array_drbssl.rb')
+    @service_name = 'ut_array_drbssl.rb'
+    @ext = DRbSSLService.ext_service(@service_name)
     @there = @ext.front
   end
 end
Index: test/drb/test_drb.rb
===================================================================
--- test/drb/test_drb.rb	(revision 35422)
+++ test/drb/test_drb.rb	(working copy)
@@ -202,7 +202,8 @@ end

 class TestDRbSafe1 < TestDRbAry
   def setup
-    @ext = DRbService.ext_service('ut_safe1.rb')
+    @service_name = 'ut_safe1.rb'
+    @ext = DRbService.ext_service(@service_name)
     @there = @ext.front
   end
 end
Index: test/drb/drbtest.rb
===================================================================
--- test/drb/drbtest.rb	(revision 35422)
+++ test/drb/drbtest.rb	(working copy)
@@ -11,7 +11,7 @@ class DRbService
   @@ruby += " -d" if $DEBUG
   def self.add_service_command(nm)
     dir = File.dirname(File.expand_path(__FILE__))
-    DRb::ExtServManager.command[nm] = "#{@@ruby} \"#{dir}/#{nm}\""
+    DRb::ExtServManager.command[nm] = [@@ruby, "#{dir}/#{nm}"]
   end

   %w(ut_drb.rb ut_array.rb ut_port.rb ut_large.rb ut_safe1.rb
ut_eval.rb ut_eq.rb).each do |nm|
@@ -65,12 +65,20 @@ end

 module DRbCore
   def setup
-    @ext = DRbService.ext_service('ut_drb.rb')
+    @service_name = 'ut_drb.rb'
+    @ext = DRbService.ext_service(@service_name)
     @there = @ext.front
   end

   def teardown
     @ext.stop_service if @ext
+    DRbService.manager.unregist(@service_name)
+    Thread.list.each {|th|
+      if th.respond_to?(:pid) && th[:drb_service] == @service_name
+        Process.kill :TERM, th.pid
+        th.join
+      end
+    }
   end

   def test_00_DRbObject
@@ -271,12 +279,20 @@ end

 module DRbAry
   def setup
-    @ext = DRbService.ext_service('ut_array.rb')
+    @service_name = 'ut_array.rb'
+    @ext = DRbService.ext_service(@service_name)
     @there = @ext.front
   end

   def teardown
     @ext.stop_service if @ext
+    DRbService.manager.unregist(@service_name)
+    Thread.list.each {|th|
+      if th.respond_to?(:pid) && th[:drb_service] == @service_name
+        Process.kill :TERM, th.pid
+        th.join
+      end
+    }
   end

   def test_01

-- 
[田中 哲][たなか あきら][Tanaka Akira]

In This Thread