今回の話は Ruby のコア開発の話で一般ユーザーには関係ありません。

ruby の make test-all で、 test/drb/drbtest.rb がファイルを読み込まれた時にスレッドを起動して、 関係ないテストの時にもスレッドが動きっぱなしで CI での SEGV などの時に余計な情報が出ていたので、 テストの前後で実行・停止するように変更しました。

対象バージョン

  • ruby 2.6.0dev (2018-10-20)

背景

Ruby の CI でたまにバックトレースが出る時に rinda や drb のスレッドが出ていて気になっていて、 rinda の方は 以前に止めた のですが、 意外と時間がかかったので、 drb の方は保留にしていたので、 Ruby 開発合宿 (日帰り) のタイミングで対処することにしました。

方針

lib の方はできるだけいじらずに test の方だけ変更するという方針で対応しました。

ただし、 remove_server で @primary_server を戻す のは lib の方を直さないと regist_server での再登録がちゃんとできないので入れました。

@queue.pop の返り値で @thread が止まるようにする のも manager.instance_variable_get(:@thread)&.kill で無理やり止めるより、 manager.instance_variable_get(:@queue)&.push(nil) で止めた方が安全そうと思って入れました。

instance_variable_get はすでに他のインスタンス変数へのアクセスに使われていたので、ここで使っても問題ないと思って使っています。

drb の動き

druby://localhost:8787 のような URI で表されるホストのポートで待ち受けて、 サイズ + Marshal したオブジェクトをやりとりして、 リモートのメソッド呼び出しをします。

直接 Marshal できないオブジェクトは DRb::DRbObject でラップされて参照として渡されます。

extservm の動き

まず lib/drb/extserv.rbDRb::ExtServ が、 lib/drb/extservm.rbDRb::ExtServManager があります。

ExtServManager が親プロセス側で DRb::ExtServ を使う子プロセス (テストの場合は test/drb/ut_*.rb) を起動して、 子プロセス側から親プロセスの DRb::ExtServManager#regist を呼び出して使えるようになったことを通知して、 親プロセス側から使い、 子プロセスは DRb::ExtServManager#unregist で登録解除してから終了、 という流れになっています。

DRbTests::DRbService の動き

test/drb/drbtest.rbDRbTests::DRbServiceDRb::ExtServManager を管理しています。

まずファイルを読み込まれた時点で add_service_command でサービス名と実行するファイルの対応を登録します。 DRb::ExtServManager.command はグローバルなハッシュなので、 test/drb/test_drbssl.rbtest/drb/test_drbunix.rb で登録される先も同じです。

initializeDRb::ExtServManager のインスタンスを作成して、 startDRb::ExtServManager#regist などをうけるための DRb::DRbServer を作成しています。 サブクラスで drbssldrbunix にできるように initialize の中で直接作成せずに別メソッドに切り出しています。

ext_service で実際に子プロセスを起動して regist 待ちをしています。

最後に finish で後始末をしています。

solaris での問題

変更を入れてみたところ、 Solaris だけで CI が失敗していました。

unstable11sext_service での regist 待ちがタイムアウトしています。

unstable11xunstable10x はサイズの読み込みの read で BUG になって落ちています。

Disqus Comments

Kazuhiro NISHIYAMA

Ruby のコミッターとかやってます。 フルスタックエンジニア(って何?)かもしれません。 About znzに主なアカウントをまとめました。

znz znz


Published